我正在使用Moq与方法接口配对.我需要测试这个接口中的方法是按照一定的顺序执行的,也是每个方法执行一定次数的.
public interface IInterface
{
void MethodOne(string foo);
void MethodTwo(string foo);
}
Run Code Online (Sandbox Code Playgroud)
// MyClass stuff ...
public async Task Run()
{
MethodOne("foo");
MethodTwo("foo");
}
// ...
Run Code Online (Sandbox Code Playgroud)
我写了这个测试来验证方法只执行了一定次数(一次):
[TestMethod]
public async Task Test()
{
var mock = new Mock<IInterface>();
var mockSequence = new MockSequence();
var obj = new MyClass();
await obj.Run();
mock.Verify(i=> i.MethodOne("foo"), Times.Once());
mock.Verify(i=> i.MethodTwo("foo"), Times.Once());
}
Run Code Online (Sandbox Code Playgroud)
这很好......
我已经尝试过这些测试来确定某个序列是否得到了适当的满足,但测试似乎总是通过.
[TestMethod]
public async Task Test()
{
var mock = new Mock<IInterface>();
var mockSequence = new MockSequence();
var obj = new MyClass();
await obj.Run();
mock.InSequence(mockSequence).Setup(i => i.MethodOne("foo"));
mock.InSequence(mockSequence).Setup(i => i.MethodTwo("foo"));
}
Run Code Online (Sandbox Code Playgroud)
应该通过,并做...
[TestMethod]
public async Task Test()
{
var mock = new Mock<IInterface>();
var mockSequence = new MockSequence();
var obj = new MyClass();
await obj.Run();
mock.InSequence(mockSequence).Setup(i => i.MethodTwo("foo")); // swapped order here
mock.InSequence(mockSequence).Setup(i => i.MethodOne("foo"));
}
Run Code Online (Sandbox Code Playgroud)
不应该通过,但确实......
您的示例测试InSequence似乎是错误的顺序.Setup在调用Run方法之前,您应该执行该操作.我假设这是一个错字,你的实际测试Setup,然后以正确的顺序调用对象.还不清楚你的模拟是如何IInterface得到的MyClass.在我的最后一个例子中,我假设它实际上是注入的......
InSequence如果你使用严格的模拟,Moq的支持似乎才有效.如果您创建Mock这样的:
var mock = new Mock<IInterface>(MockBehavior.Strict);
Run Code Online (Sandbox Code Playgroud)
然后这将工作:
mock.InSequence(mockSequence).Setup(i => i.MethodOne("foo"));
mock.InSequence(mockSequence).Setup(i => i.MethodTwo("foo"));
Run Code Online (Sandbox Code Playgroud)
虽然失败了:
mock.InSequence(mockSequence).Setup(i => i.MethodTwo("foo")); // swapped order here
mock.InSequence(mockSequence).Setup(i => i.MethodOne("foo"));
Run Code Online (Sandbox Code Playgroud)
注意,出现的错误是关于缺少相应设置的方法...而不是被称为不按顺序调用,如果你不期望它,这不一定是最容易解码的.
如果您不想/不能使用严格的模拟,那么替代方法是使用回调实现您自己的序列检查.像这样的东西:
int sequence = 1;
mock.Setup(i => i.MethodOne("foo"))
.Callback(()=>Assert.AreEqual(1, sequence++, "Method called out of sequence"));
mock.Setup(i => i.MethodTwo("foo"))
.Callback(() => Assert.AreEqual(2, sequence++, "Method called out of sequence"));
var obj = new MyClass(mock.Object);
await obj.Run();
Run Code Online (Sandbox Code Playgroud)
这可能比你想要的更偏离主题,但NSubstitute是一个很棒的模拟库,可以很好地处理这个问题。在 NSubstitute 中它只是:
var mock = Substitute.For<IInterface>();
var obj = new MyClass();
await obj.Run();
Received.InOrder(() => {
mock.MethodOne("foo");
mock.MethodTwo("foo");
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2160 次 |
| 最近记录: |