具有多个回调的Moq单元测试?

时间:2015-06-24 17:11:44

标签: c# unit-testing nunit moq

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

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

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)始终为false,即使第一次调用时为true。 Assert.IsTrue(_response)也是如此,但我怀疑我可以通过多次返回修复它。

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

示例测试:

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

1 个答案:

答案 0 :(得分:2)

由于某种原因,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表达式中给定谓词匹配的参数调用一次。