Moq: Как очистить ожидания от фиктивного объекта? - PullRequest
2 голосов
/ 27 июня 2010

Пример - я хочу проверить, что снайпер уведомляет вид только о добавленных предметах.

[Test]
    public void NotifiesViewOfLoss_IfCloseEventReceivedForSnipedItems()
    {
        _sniper.AddItem(TestConstants.ItemNo54321);
        _sniper.AddItem(TestConstants.ItemNo65432);

        _sniper.AuctionClosedFor(TestConstants.ItemNo65432);
        _mockView.Verify(view => view.UpdateStatus(TestConstants.ItemNo65432, AuctionSniperStatus.Lost));

        _sniper.AuctionClosedFor(TestConstants.ItemNo54321);
        _mockView.Verify(view => view.UpdateStatus(TestConstants.ItemNo54321, AuctionSniperStatus.Lost));

        _sniper.AuctionClosedFor(7);

        // doesn't work
        //_mockView.Verify(view => view.UpdateStatus(It.IsAny<int>(), It.IsAny<AuctionSniperStatus>()),
        //                Times.Never() );
    }

Строка Times.Never не работает - потому что она соответствует одному из предыдущих вызовов. Я знаю, что есть и другие альтернативы:

  • установить новое ожидание для броска при вызове (как показано выше)
  • как указание 7 вместо IsAny ()
  • разделение теста на 2 теста

Ответы [ 3 ]

1 голос
/ 27 июня 2010

В этом случае, когда обновление статуса в представлении не дает какого-либо «результата», который вы могли бы утверждать, я бы также пошел на строгие проверки.Таким образом, вы устанавливаете точно вызовов, которые вы ожидаете совершить на макетируемом объекте (и точное количество этих вызовов).Когда вы измените тип макета, ваш тест мгновенно станет правильным.

Этот способ намного лучше, чем ваши первые два варианта (потому что он провалит тест, даже если вы не угадаете правильные значения параметров или забудете установить ожидание, которое вызовет исключение),также более читабельно (по крайней мере, ИМХО).

Что касается разделения тестов, всегда желательно, чтобы модульные тесты были как можно меньше.Таким образом, вопрос заключается в том, хотите ли вы проверить, что происходит, когда у вас есть этот неправильный вызов после двух правильных вызовов?Или достаточно одного неверного звонка?

1 голос
/ 27 июня 2010

Если вы хотите утверждать, что only вызваны указанные вами методы, вы можете рассмотреть возможность использования строгого макета для _mockView в этом тесте.

0 голосов
/ 05 ноября 2015

Это старый пост, но для полноты картины в Moq теперь есть способ сброса счетчиков проверки (https://stackoverflow.com/a/23549214/179311):

).
_sniper.AuctionClosedFor(TestConstants.ItemNo54321);
_mockView.Verify(view => view.UpdateStatus(TestConstants.ItemNo54321, AuctionSniperStatus.Lost));

_mockView.ResetCalls();

_sniper.AuctionClosedFor(7);
_mockView.Verify(view => view.UpdateStatus(It.IsAny<int>(), It.IsAny<AuctionSniperStatus>()),
                 Times.Never() );
...