对模拟对象的期望似乎没有得到满足(最小起订量)
我在 Moq 中遇到了一些奇怪的行为 - 尽管我设置了一个模拟对象以某种方式行事,然后在我正在测试的对象中以完全相同的方式调用该方法,但它的反应就像该方法是从来没有打电话过。
我正在尝试测试以下控制器操作:
public ActionResult Search(string query, bool includeAll)
{
if (query != null)
{
var keywords = query.Split(' ');
return View(repo.SearchForContacts(keywords, includeAll));
}
else
{
return View();
}
}
我的单元测试代码:
public void SearchTestMethod() // Arrange
var teststring = "Anders Beata";
var keywords = teststring.Split(' ');
var includeAll = false;
var expectedModel = dummyContacts.Where(c => c.Id == 1 || c.Id == 2);
repository
.Expect(r => r.SearchForContacts(keywords, includeAll))
.Returns(expectedModel)
.Verifiable();
// Act
var result = controller.Search(teststring, includeAll) as ViewResult;
// Assert
repository.Verify();
Assert.IsNotNull(result);
AssertThat.CollectionsAreEqual<Contact>(
expectedModel,
result.ViewData.Model as IEnumerable<Contact>
);
}
其中 AssertThat
只是我自己的一个类,带有一堆断言助手(因为 Assert
code> 类无法使用扩展方法进行扩展...叹息...)。
当我运行测试时,它在 repository.Verify()
行失败,并出现 MoqVerificationException
:
Test method MemberDatabase.Tests.Controllers.ContactsControllerTest.SearchTestMethod() threw exception: Moq.MockVerificationException: The following expectations were not met: IRepository r => r.SearchForContacts(value(System.String[]), False)
如果我删除 repository.Verify()
,集合断言失败,告诉我返回的模型为 null
。 我已经调试并检查了 query != null
,并且我被带入了运行代码的 if
块部分。 那里没有问题。
为什么这不起作用?
I'm experiencing some odd behavior in Moq - despite the fact that I setup a mock object to act a certain way, and then call the method in the exact same way in the object I'm testing, it reacts as if the method was never called.
I have the following controller action that I'm trying to test:
public ActionResult Search(string query, bool includeAll)
{
if (query != null)
{
var keywords = query.Split(' ');
return View(repo.SearchForContacts(keywords, includeAll));
}
else
{
return View();
}
}
My unit test code:
public void SearchTestMethod() // Arrange
var teststring = "Anders Beata";
var keywords = teststring.Split(' ');
var includeAll = false;
var expectedModel = dummyContacts.Where(c => c.Id == 1 || c.Id == 2);
repository
.Expect(r => r.SearchForContacts(keywords, includeAll))
.Returns(expectedModel)
.Verifiable();
// Act
var result = controller.Search(teststring, includeAll) as ViewResult;
// Assert
repository.Verify();
Assert.IsNotNull(result);
AssertThat.CollectionsAreEqual<Contact>(
expectedModel,
result.ViewData.Model as IEnumerable<Contact>
);
}
where AssertThat
is just a class of my own with a bunch of assertion helpers (since the Assert
class can't be extended with extension methods... sigh...).
When I run the test, it fails on the repository.Verify()
line, with a MoqVerificationException
:
Test method MemberDatabase.Tests.Controllers.ContactsControllerTest.SearchTestMethod() threw exception: Moq.MockVerificationException: The following expectations were not met: IRepository r => r.SearchForContacts(value(System.String[]), False)
If I remove repository.Verify()
, the collection assert fails telling me that the model returned is null
. I have debugged and checked that query != null
, and that I am taken into the part of the if
block where the code is run. No problems there.
Why doesn't this work?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我怀疑这是因为您传递到模拟存储库的数组(
teststring.Split(' ')
的结果)与实际从 Search 方法传入的对象不是同一对象(query.Split(' ')
的结果)。尝试将设置代码的第一行替换为:
... 这会将传递给模拟的数组的每个元素与
keywords
数组中的相应元素进行比较。I suspect it's because the array you're passing into your mocked repository (the result of
teststring.Split(' ')
) is not the same object as the one that actually gets passed in from the Search method (the result ofquery.Split(' ')
).Try replacing the first line of your setup code with:
... which will compare each element of the array passed to your mock with the corresponding element in the
keywords
array.