具有多个回调的最小起订量单元测试?

Moq Unit testing with multiple callbacks?

(首先,请原谅伪代码。那里没有选择。)

我是单元测试的新手,遇到了一些麻烦。我正在尝试对对服务进行两次调用的控制器方法进行单元测试,例如

public JsonResult Submit(FormModel form){
    RequestObj obj = createRequestObj(form);
    bool response = _someService.SubmitRequest(obj);

    if(form.RerunWithAnotherValue) {
        obj.SomeProp = "New Value";
        obj.SomeOtherProp = false;
        _someService.SubmitRequest(obj);
    }

    return new JsonResult {
        Data = new { status = "OK" }
    };
}

不用重新提交的条件值,测试一下就很简单了:

protected bool _response;
protected RequestObj _request;
...
_someServiceMock.Setup(x => x.SubmitRequest(It.IsAny<RequestObj>()))
          .Returns(_response)
          .Callback((RequestObj request) =>
          {  
              _request = request;
          })
          .Verifiable(); 

然后我可以使用 _request 进行测试。但是在有条件的情况下,_request 的值始终等于第二次服务调用的值。所以如果我想断言 SomeOtherProp 是真的,它总是会因为第二个而失败。

Assert.IsTrue(_request.SomeOtherProp) 始终为假,即使在第一次调用时为真。 Assert.IsTrue(_response) 也是如此,但我怀疑我可以用多个 Returns.

来解决这个问题

有没有办法通过回调只分配第一个调用而忽略另一个?更好的是,我可以将它们保存到不同的对象并分别进行测试吗?我查看了 SetupSequence,但 .Callback 在那里不起作用。有人能指出我正确的方向吗?

示例测试:

[Test]
public void request_object_has_property() {
    Assert.IsTrue(_request.SomeOtherProp.Value);
}

Verify 是否出于某种原因不适合您的需求?您可以像这样验证这两个调用:

// first call
_someServiceMock.Verify(x => x.SubmitRequest(It.Is<RequestObj>(
    o => o.SomeOtherProp), Times.Once());

// second call
_someServiceMock.Verify(x => x.SubmitRequest(It.Is<RequestObj>(
    o => o.SomeProp == "New Value" && !o.SomeOtherProp), Times.Once());

这验证 SubmitRequest 被调用一次,其参数与 It.Is 表达式中给定的谓词相匹配。