#c_sharp #юнит_тесты #moq
Не могу разобраться для чего используется 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 (кроме вот этой неполноценной), она вообще есть?
Ответы
Ответ 1
Да Вы всё верно поняли. Насколько можно судить из статьи этот метод может быть использован для проверки вызова ранее вызова метода определённого в 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 хотя-бы потому, что он ну уж совсем не очевиден. Разработка ведётся на гитхабе и кроме детальной документации на которую вы сослались есть быстрый старт и примеры использования.
Комментариев нет:
Отправить комментарий