我正在为现有的Web API 2项目编写单元测试。我正在使用Ploeh Autofixture
和Moq
。
测试方法: 已更新
[Test]
public async Task Service1_TestMethod() {
//some code here
var fakeemail = FakeBuilder.Create<string>("test1234@test.com");
var fakeUserInvite =
FakeBuilder.Build<UserInvite>()
.With(i => i.EmailAddress, fakeemail)
.With(i => i.Username, fakeemail)
.Create();
var fakeUserToken = FakeBuilder.Create<string>();
var fakeHttpResponseMessage =
Fixture.Build<HttpResponseMessage>()
.With(h => h.StatusCode, HttpStatusCode.OK).Create();
//Here i am mocking another service method. Whose response is HttpResponseMessage.
Service2.Setup(i => i.AddUser(fakeUserInvite, fakeUserToken))
.ReturnsAsync(fakeHttpResponseMessage);
var result = await Service1.AddUser( /* */);
}
Service1方法:
public async Task<bool> AddUser(/* */)
{
var response = await Service2.AddUser(userInvite, userToken); // response is null even after mocking it.
// Add user code follows bassed on the above response.
}
如果我评论Service2.AddUser
电话,那么一切正常。除了这个调用之外,该方法中还有很多代码。我只有这个电话有问题。如果此调用返回模拟的HttpResponseMessage
,则一切正常。
Service2
是一个外部API。我只是想知道如何mock
HttpResponseMessage
。任何帮助表示赞赏。
答案 0 :(得分:9)
您创建的存根:
service2.Setup(i => i.AddUser(fakeUserInvite, fakeUserToken))
.ReturnsAsync(fakeHttpResponseMessage);
要求使用与fakeUserInvite
和fakeUserToken
引用的相同对象进行实际调用,以便Moq返回fakeHttpResponseMessage
。
这是因为Moq's argument matching验证存根中指定的参数与实际调用中的参数相等。如果不是,则存根不会匹配,Moq将返回方法返回类型的默认值 - 在本例中为null
,因为HttpResponseMessage
是引用类型。< / p>
要解决此问题,您可以确保将fakeUserInvite
和fakeUserToken
引用传递给实际的service2.AddUser
来电,或者您可以使用稍微不那么具体的{{3} }。
以下是一个例子:
service2.Setup(i => i.AddUser(
It.Is<UserInvite>(u => u.EmailAddress == fakeEmail &&
u.Username == fakeEmail),
fakeUserToken))
.ReturnsAsync(fakeHttpResponseMessage);
我们在此声明应该使用以下方法调用AddUser
方法:
UserInvite
对象,其EmailAddress
和Username
属性与fakeEmail
的值相同,作为第一个参数fakeUserToken
相同的值作为第二个参数如果这些参数的实际值对您的特定测试场景不重要,那么无论参数fakeHttpResponseMessage
是什么,您都可以告诉Moq 总是返回AddUser
正在呼吁说:
service2.Setup(i => i.AddUser(
It.IsAny<UserInvite>(),
It.IsAny<string>()))
.ReturnsAsync(fakeHttpResponseMessage);