Ожидания от Mock Object, похоже, не оправдались (Moq)

У меня какое-то странное поведение в 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, где запускается код. Там нет проблем.

Почему это не работает?


person Tomas Aschan    schedule 02.08.2009    source источник


Ответы (1)


Я подозреваю, что это связано с тем, что массив, который вы передаете в свой фиктивный репозиторий (результат teststring.Split(' ')), не является тем же объектом, что и тот, который фактически передается из метода поиска (результат query.Split(' ')).

Попробуйте заменить первую строку кода установки на:

repository.Expect(r => r.SearchForContacts(
    It.Is<String[]>(s => s.SequenceEqual(keywords)), includeAll))

... который будет сравнивать каждый элемент массива, переданного вашему макету, с соответствующим элементом в массиве keywords.

person Matt Hamilton    schedule 02.08.2009
comment
Спасибо! Это сразу подействовало! =) Кажется, мне нужно прочитать о Moq, и особенно о том, когда и как использовать конструкции It.... - person Tomas Aschan; 03.08.2009