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?
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 of query.Split(' ')
).
Try replacing the first line of your setup code with:
repository.Expect(r => r.SearchForContacts(
It.Is<String[]>(s => s.SequenceEqual(keywords)), includeAll))
... which will compare each element of the array passed to your mock with the corresponding element in the keywords
array.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With