Страницы

Поиск по вопросам

понедельник, 11 февраля 2019 г.

Для чего используется Mock.Setup().Verifiable()?

Не могу разобраться для чего используется Mock.Verifiable(), если я правильно понимаю, такой код:
var mockContainer = new Mock(MockBehavior.Strict, StorageUri); mockContainer.Setup(c => c.GetBlockBlobReference(It.IsAny())) .Returns(mockBlobItem.Object); // ... mockContainer.Verify(c => c.GetBlockBlobReference(It.IsAny()), Times.AtLeastOnce);
Будет эквивалентен такому:
var mockContainer = new Mock(MockBehavior.Strict, StorageUri); mockContainer.Setup(c => c.GetBlockBlobReference(It.IsAny())) .Returns(mockBlobItem.Object) .Verifiable(); // ... mockContainer.Verify();
Есть ещё третий вариант:
var mockContainer = new Mock(MockBehavior.Strict, StorageUri); mockContainer.Setup(c => c.GetBlockBlobReference(It.IsAny())) .Returns(mockBlobItem.Object); // ... mockContainer.Verify();
Изучил множество примеров, так вот там используются, как правило, второй или третий варианты. А ещё есть .VerifyAll().
Как правильно и почему? Какие есть особенности и подводные камни? Как эти варианты зявисят от моделей поведения Strict и Loose?

Не смог найти документацию к Moq (кроме вот этой неполноценной), она вообще есть?


Ответ

Да Вы всё верно поняли.
Насколько можно судить из статьи этот метод может быть использован для проверки вызова ранее вызова метода определённого в Setup.
var thing = new Thing() { Id = 1 }; var mockMapper = new Mock(); mockMapper.Setup(p => p.Save(thing)).Verifiable();
// do stuff
mockMapper.Verify();
Кроме того согласно англоязычного ответа желательно не использовать этот подход т.к. он явно противоречит паттерну AAA. Противоречие заключается в том, что подготовка данных для тестирования (Arrange) и описание того, что должно быть проверено (Assert) происходит в методе Setup
Сами же мейнтейнеры проекта озвучивают ещё рад случаев почему не стоит продолжать развивать такое АПИ
Тем не менее этот подход может быть оправдан к примеру необходимостью избежать дублитрования кода.
Единственный случай, когда такой подход нельзя будет использовать это при необходимости проверить количество вызовов. В этом случае Вы можете использовать только метод Verify с полным описание ожидаемого вызова:
mock.Verify(c => c.Method(It.Is(x => x == "x")), Times.Once);
По поводу использования Verify без параметров. Он будет проверять только методы которые Вы в сетапе отметили при помощи метода Verifiable
var mockContainer = new Mock(MockBehavior.Strict, StorageUri); mockContainer.Setup(c => c.GetBlockBlobReference(It.IsAny())) .Returns(mockBlobItem.Object) .Verifiable(); // ... mockContainer.Verify();
Если же вы хотите проверить был ли вызван метод который не был отмечем как Verifiable, можно использовать метод VerifyAll
var mockContainer = new Mock(MockBehavior.Strict, StorageUri); mockContainer.Setup(c => c.GetBlockBlobReference(It.IsAny())) .Returns(mockBlobItem.Object); // ... // Verify - не будет проверять в этом случае // т.к. Вы не получите ошибку даже если метод не был вызван ни разу // для такого случая можно сделать так mockContainer.VerifyAll();
Но лично я бы не использовал VerifyAll хотя-бы потому, что он ну уж совсем не очевиден.

Разработка ведётся на гитхабе и кроме детальной документации на которую вы сослались есть быстрый старт и примеры использования.

Комментариев нет:

Отправить комментарий