我有一个方法,调用模拟对象的另一个方法,其参数是根据我传递给测试函数的参数计算的。
如何验证我测试的方法调用的方法是否正确调用
我正在使用Moq。
编辑:
因为没有人得到我的意思(或者我不明白你们为我解决了这个问题的事实)我会更加具体。
我有以下方法签名:
IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state);
在其中应该实例化一个SocketAsyncEventArgs对象并使用正确的SocketAsyncEventArgs调用它的SetBuffer方法。
SocketAsyncEventArgs是实现细节,但它是实现我之后的功能的唯一方法,因此我必须检查它是否正确调用了SetBuffer方法。
如何确保BeginWrite()实现确实使用正确的参数调用SetBuffer?
编辑2:
这里有一些代码来澄清我的意思:
public IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
{
// No mocking can be done here
SocketAsyncEventArgs args = new SocketAsyncEventArgs
{
// Proper initialization. Should be verified as well.
};
args.SetBuffer(buffer, offset, size);
Client.SendAsync(args);
}
答案 0 :(得分:6)
您可以测试是否通过Verify
方法调用该方法。如果被调用的方法没有返回任何内容,那么你不需要Setup
。我更喜欢这个,而不是Setup或Expect / VerifyAll方法,因为它更像是AAA。
[Test]
public void ShoudlCallMockMethod()
{
var mocked = new Mock<IDoStuff>();
var target = new ClassToTest(mocked.Object);
target.DoStuff();
mocked.Verify(x => x.CallMyMethod(It.IsAny<string>());
}
这里它希望用任何参数调用CallMyMethod
。如果您知道传入的确切参数并想要检查,那么执行
mocked.Verify(x => x.CallMyMethod("exactstring"));
如果你想要传递更复杂的匹配(对于有很多araguments的复杂对象很有用),那就得look at another answer I did with using a matcher。
如果你想确保只调用一次,你也可以添加Times.AtMostOnce()
[编辑]
根据您的编辑和注释,您不需要模拟args对象,但如果您仍想验证参数是否已设置,则可以在Client.SendAsync方法上进行验证,前提是可以模拟(我会建议你应该瞄准,如果你还没有这样做)。我提供的关于匹配者的链接应该有帮助。
至于你在过去几年的评论中提出的问题,记录/重播 - 验证&gt; Expect / Setup-Verify&gt; [配置] -Verify。它可以归结为模拟技术,但主要是由于在c#3.5中引入了lambda表达式,然后转向了AAA。您真正想要的是遵循AAA原则的小型可读测试,因此Expect / Setup-VerifyAll确实在编配阶段具有Assert(您必须回头查看正在验证的内容)。因此,除非模拟方法需要返回某些内容,否则您不需要安装程序,只需验证该方法是在Assert阶段调用的。
答案 1 :(得分:1)
我相信它会验证你在调用Setup
时传入的参数是否等于真实代码传入的参数。
QuickStart guide有更有趣的约束的例子。遗憾的是,目前无法链接到外部API指南:(
编辑:我怀疑你想要的东西:
mock.Setup(foo => foo.SendAsync(It.Is<AsyncCallback>(x =>
{
// Whatever you need to test here
return x.Buffer.Length == 15 &&
x.Offset = 10 &&
x.Count = 5;
}));
答案 2 :(得分:0)
下面的测试失败,因为设置期望名为value的参数被传递为“预期”未被满足。我想这就是你追求的目标?
[TestClass]
public class MyTests
{
[TestMethod]
public void TestParameterExpectation()
{
var mock = new Mock<IInterface>();
mock.Setup(x => x.CallMe("expected"));
CallIt("not expected", mock.Object);
mock.VerifyAll();
}
public void CallIt(string value, IInterface callit)
{
callit.CallMe(value);
}
}
public interface IInterface
{
void CallMe(string value);
}