使用Moq和AutoFixture对单元测试API进行Mock HttpResponseMessage

时间:2016-08-18 10:21:35

标签: c# unit-testing asp.net-web-api2 moq autofixture

我正在为现有的Web API 2项目编写单元测试。我正在使用Ploeh AutofixtureMoq

测试方法:    已更新

 [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。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:9)

您创建的存根:

service2.Setup(i => i.AddUser(fakeUserInvite, fakeUserToken))
        .ReturnsAsync(fakeHttpResponseMessage);

要求使用与fakeUserInvitefakeUserToken引用的相同对象进行实际调用,以便Moq返回fakeHttpResponseMessage

这是因为Moq's argument matching验证存根中指定的参数与实际调用中的参数相等。如果不是,则存根不会匹配,Moq将返回方法返回类型的默认值 - 在本例中为null,因为HttpResponseMessage是引用类型。< / p>

要解决此问题,您可以确保将fakeUserInvitefakeUserToken引用传递给实际的service2.AddUser来电,或者您可以使用稍微不那么具体的{{3} }。

以下是一个例子:

service2.Setup(i => i.AddUser(
            It.Is<UserInvite>(u => u.EmailAddress == fakeEmail &&
                                   u.Username == fakeEmail),
            fakeUserToken))
        .ReturnsAsync(fakeHttpResponseMessage);

我们在此声明应该使用以下方法调用AddUser方法:

  1. UserInvite对象,其EmailAddressUsername属性与fakeEmail的值相同,作为第一个参数
  2. fakeUserToken相同的值作为第二个参数
  3. 如果这些参数的实际值对您的特定测试场景不重要,那么无论参数fakeHttpResponseMessage是什么,您都可以告诉Moq 总是返回AddUser正在呼吁说:

    service2.Setup(i => i.AddUser(
                It.IsAny<UserInvite>(),
                It.IsAny<string>()))
            .ReturnsAsync(fakeHttpResponseMessage);