如何使用正确的参数测试方法的调用?

the*_*row 2 c# unit-testing moq

我有一个方法,调用模拟对象的另一个方法,其参数是根据我传递给测试函数的参数计算的.
如何验证我测试的方法正在调用的方法是否正确调用.
我正在使用Moq.

编辑:
因为没有人得到我的意思(或者我不明白你们为我解决了这个问题的事实)我会更加具体.
我有以下方法签名:

IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state);
Run Code Online (Sandbox Code Playgroud)

在里面它应该实例化一个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);
}
Run Code Online (Sandbox Code Playgroud)

aqw*_*ert 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>());
}
Run Code Online (Sandbox Code Playgroud)

这里它期望调用CallMyMethod任何参数.如果你知道传入的确切参数并想要检查那么做

mocked.Verify(x => x.CallMyMethod("exactstring"));
Run Code Online (Sandbox Code Playgroud)

如果你想要更复杂的传入匹配(对于具有许多araguments的复杂对象很有用),那么看看我使用匹配器做的另一个答案.

如果要确保仅调用一次,也可以添加Times.AtMostOnce()

[编辑]

基于您的编辑和注释,您不需要模拟args对象,但如果您仍然想验证参数是否已设置,那么您可以在Client.SendAsync方法上进行验证,前提是可以模拟(我建议你应该这样做)瞄准,如果你还没有这样做).我提供的关于匹配器的链接应该有帮助.

至于您在过去几年的评论中提出的问题,记录/重放 - 验证>期望/设置 - 验证> [设置] - 验证已经发生了变化.它可以归结为模拟技术,但主要是由于在c#3.5中引入了lambda表达式,然后转向了AAA.您真正想要的是遵循AAA原则的小型可读测试,因此Expect/Setup-VerifyAll确实在编配阶段具有Assert(您必须回头查看正在验证的内容).因此,除非模拟方法需要返回某些内容,否则您不需要安装程序,只需验证是否在Assert阶段调用了该方法.