如何验证Moq中的参数?



我正在编写测试用例并获得编译错误。return在下面的语句中不起作用。

//Moq
//Error: '.' cannot be applied to operand of type 'void'. This gives error before ".Returns".
private Mock<ITestDomain> _testDomain;
//test
[TestMethod]
public void PassParams()
{
//arrange
var opentickResponse = new OpenTicketResponse();
opentickResponse.Tickets.Add(new Ticket { TickId = "ticket123"});
opentickResponse.Tickets.Add(new Ticket { TickId = "ticket456"});


_testDomain.Setup(x => x.OpenTicketing(null)).Returns(openTickResponse);
//act
var response = _target.Execute(_request);

//assert
Assert.IsNotNull(response, "response = null");
Assert.AreEqual("name", response.Ticket.Countryname);


_testDomain.Verify(x => x.OpenTicket(null)).Returns(x => (x[0] as OpenTicketRequest).phone.ID == _request.phone.ID && 
(x[0] as OpenTicketRequest).ActiveContract.IDnumber == _request.ActiveContract.IDnumber);
}

我这样写,但这显示错误。Verify语句是否错误?

Moq MethodVerify没有返回,如果它试图验证的函数没有在模拟对象上调用,它会抛出。它是一个void方法。所以不能叫a.Verify().Returns因为a.Verify()是空的。这就是编译错误的原因。

至于你实际上想要实现的我有点困惑,你正在测试target.Execute,但是你的代码没有显示你将_testDomain注入target,所以据我所知,它基本上没有使用。也许你应该检查一下Moq是否真的像你想象的那样。这是一个公平的起点。

Verify用于检查特定方法是否被调用,并且可以配置为检查方法被调用的次数和用于调用它的参数,例如下面将检查OpenDocument()被调用一次,null作为参数值:

_testDomain.Verify(x => x.OpenDocument(null), Times.Once);

Verify不用于检查方法调用的结果。如果您想要检查一个方法的结果,您需要一个调用该方法、记录结果并对结果做出断言的测试。甚至可以在相同的测试中这样做,而不是使用Verify:

var result = _testDomain.OpenDocument(null);
var openDocumentRequest = result[0] as OpenDocumentRequest;
Assert.AreEqual(_request.phone.ID, openDocumentRequest.phone.ID);
Assert.AreEqual(_request.ActiveContract.IDnumber, openDocumentRequest.ActiveContract.IDnumber);
  • 我假设这是单元测试

我发现这段代码有很多问题:

  1. 您正在设置testDomain而没有下划线_,但您正在使用下划线断言_testDomain。这两者有什么区别吗?为什么会有两个呢?
  2. 你从来没有模拟OpenDocument方法,所以在目标中它将返回null
  3. 你在嘲笑一个叫做OpenDocumentation的方法,但是你在断言OpenDocument.
  4. 我假设你的目标不只是调用方法与null参数在那里。所以与其用null来嘲弄他们不如用It.IsAny<WhatEverOpenDocumentsReceives>()
  5. 在单元测试中,你只关注一个要测试的单元。在你的例子中,你的单位是目标的一个实例。其他一切都应该被嘲笑。如果其他所有东西都在某个点上被嘲笑,这意味着_testDomain/testDomain不是真实的。最后一条语句尝试测试是否调用了testDomain中的方法并返回了一些值。我认为您不需要测试模拟方法是否返回某个结果。既然你是嘲笑它的人,你为什么要呢?

为了验证参数,您可以使用Callback()功能。在您的示例中,它可能看起来像:

OpenDocumentRequest actualRequest = null;
_testDomain.Setup(x => x.OpenDocument(It.IsAny<OpenDocumentRequest>()))
.Callback((OpenDocumentRequest value) => { actualRequest = value; });
// act
var response = _target.Execute(_request);
// validate actual request
Assert.IsNotNull(actualRequest);
Assert.AreEqual(_request.phone.ID, actualRequest.phone.ID);
Assert.AreEqual(_request.ActiveContract.IDnumber, actualRequest.ActiveContract.IDnumber);

最新更新