如何验证未在Moq中调用该方法?
它有类似 AssertWasNotCalled 的东西吗?
更新:从 3.0 版开始,可以使用新语法:
mock.Verify(foo => foo.Execute("ping"), Times.Never());
使用该Times.Never()
选项在测试后运行验证。
_mock.Object.DoSomething()
_mock.Verify(service => service.ShouldntBeCalled(), Times.Never());
更新:从第 3 版开始,请检查上述问题的更新或以下 Dann 的回答。
要么,让你的模拟严格,这样如果你调用一个你没有期望的方法,它就会失败
new Mock<IMoq>(MockBehavior.Strict)
或者,如果您希望您的模拟是松散的,请使用 .Throws( Exception )
var m = new Mock<IMoq>(MockBehavior.Loose);
m.Expect(a => a.moo()).Throws(new Exception("Shouldn't be called."));
盗自:John Foster 对问题的回答,“需要帮助以更好地理解 Moq”
您可能要测试的一件事是,当将 65 岁以上的人传递给方法时,不会调用 pay 方法
[Test] public void Someone_over_65_does_not_pay_a_pension_contribution() { var mockPensionService = new Mock<IPensionService>(); var person = new Person("test", 66); var calc = new PensionCalculator(mockPensionService.Object); calc.PayPensionContribution(person); mockPensionService.Verify(ps => ps.Pay(It.IsAny<decimal>()), Times.Never); }
这在 Moq 的最新版本中不起作用(至少从 3.1 开始),它应该
Verify
在答案中提到的方法中指定。
实际上,最好.AtMost(0)
在 Returns 语句之后指定。
var m = new Mock<ISomething>();
m.Expect(x => x.Forbidden()).Returns("foo").AtMost(0);
虽然“投掷”也有效,AtMost(0)
但恕我直言更具表现力。
假设你有这个方法并且你想测试它没有被调用
//Setup
var databaseSessionMock = new Mock<IDatabaseSession>();
databaseSessionMock.Setup(m => m.Commit()).Returns(true).Verifiable();
RepositoryFactory.Configure<IDatabaseSession>(databaseSessionMock.Object);
你可以像这样测试
databaseSessionMock.Verify(m => m.Commit(It.IsAny()), Times.Never(), "Database Session mock object was not used");
我意识到这是一个非常古老的问题,但它刚刚出现在我的侧边栏中,我想添加我的解决方案。
作为设置的一部分,许多单元测试似乎模拟了几个功能,但在测试期间并未使用。
当然最好启用严格模拟(这意味着任何未明确设置的内容都会引发异常),然后不要设置任何您不希望调用的函数。或者换一种说法,只设置一个测试期望调用的函数,其他任何东西都会抛出异常。
var thingBeingTested = new Mock<IThink>(MockBehaviour.Strict);
thingBeingTested.ThisWillThrowAnExceptionBecauseItHasNotBeenMocked();
VerifyNoOtherCalls
(需要最小起订量 4.8 或更高版本)这个答案是一种间接的方法。不是检查一个特定的方法没有被调用,而是检查一般情况下没有发生意外的调用。
考虑到对模拟的彻底测试做了两件事:
如果您已经在执行第 1 步,则添加第 2 步很简单:
// Step 1 (if relevant - see note below)
mock.Verify(..., Times.Exactly(2));
mock.Verify(..., Times.Once());
// ...
// Step 2
mock.VerifyNoOtherCalls();
笔记
使用 .AtMostOnce();
真实测试后,再次调用该方法。如果它抛出异常,它就会被调用。