Ожидания по макетному объекту, похоже, не оправдались (Moq)
-
10-07-2019 - |
Вопрос
Я испытываю некоторое странное поведение в 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
класс не может быть расширен с помощью методов расширения...вздох...).
Когда я запускаю тест, он завершается с ошибкой на 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
блок, в котором выполняется код.Здесь никаких проблем нет.
Почему это не работает?
Решение
Я подозреваю, что это потому, что массив, который вы передаете в свой издевательский репозиторий (результат teststring.Split(' ')
) не является тем же объектом, что и тот, который фактически передается из метода поиска (результат query.Split(' ')
).
Попробуйте заменить первую строку вашего установочного кода на:
repository.Expect(r => r.SearchForContacts(
It.Is<String[]>(s => s.SequenceEqual(keywords)), includeAll))
...который будет сравнивать каждый элемент массива, переданный вашему макету, с соответствующим элементом в keywords
массив.