模拟使用Moq的抽象类

我有以下抽象类和测试方法。 使用“Moq”我得到了下面的错误:

我的Abstact课程:

   public abstract class UserProvider
{ 
    public abstract UserResponseObject CreateUser(UserRequestObject request, string userUrl);

    public abstract bool IsUserExist(UserRequestObject request, string userUrl);
}

测试等级:

  [TestMethod()]
    public void CreateUserTest()
    {
        var mockUserProvider = new Mock<UserProvider>(MockBehavior.Loose);

    //GetUserRequestObject is local method to set data

         mockUserProvider.
            Setup(u => u.CreateUser(GetUserRequestObject(), ""))
            .Returns(new UserResponseObject { uid = "123", uri = userUri }).Verifiable();

         var userProvider = mockUserProvider.Object.CreateUser(GetUserRequestObject(), "");

         mockUserProvider.Verify(u => u.CreateUser(GetUserRequestObject(), ""));
    }

错误信息 :

Moq.MockException:预期在模拟上调用至少一次,但从未执行:u => u.CreateUser(.GetUserRequestObject(),“”)

任何人都请解释一下,为什么我收到这条消息以及如何解决它?


你得到这个错误的原因是因为你正在设定对象的特定实例的期望:

mockUserProvider.Verify(u => u.CreateUser(GetUserRequestObject(), ""));

这在很大程度上取决于如何实施该方法。 例如, GetUserRequestObject()这个实现将在每次调用时创建一个新实例,并且验证总是失败:

  private UserRequestObject GetUserRequestObject()
  {
     return new UserRequestObject();
  }

而返回相同的实例进行设置和验证将会成功:

  private UserRequestObject u = new UserRequestObject();
  private UserRequestObject GetUserRequestObject()
  {
     return u;
  }

而不是依赖于一个确切的实例(即避免比较2个引用),你可以改为检查任何实例:

mockUserProvider.Verify(u => u.CreateUser(It.IsAny<UserRequestObject>(),
                        It.IsAny<string>()), Times.Once);

或者优选地,符合特定标准的实例(假设GetUserRequestObject()具有被设置为Bob的属性Name

mockUserProvider.Verify(u => u.CreateUser(
                        It.Is<UserRequestObject>(x => x.Name == "Bob"),
                        It.Is<string>(s => s == "")));

您的GetUserRequestObject()可能会返回2个不同的UserRequestObject对象实例。

确保使用相同的实例来设置期望值并通过调用进行验证。 (否则,在设置期望值时使用It.IsAny<UserRequestObject>


Moq检查对象的引用。 您应该验证并传递给您在setup方法中使用的相同对象:

public void CreateUserTest()
{
    var mockUserProvider = new Mock<UserProvider>(MockBehavior.Loose);

//GetUserRequestObject is local method to set data
     var user = GetUserRequestObject();

     mockUserProvider.
        Setup(u => u.CreateUser(user, ""))
        .Returns(new UserResponseObject { uid = "123", uri = userUri }).Verifiable();

     var userProvider = mockUserProvider.Object.CreateUser(user, "");

     mockUserProvider.Verify(u => u.CreateUser(user, ""));
}

或者,您可以检查传递给方法的任何对象:

public void CreateUserTest()
{
    var mockUserProvider = new Mock<UserProvider>(MockBehavior.Loose);

//GetUserRequestObject is local method to set data

     mockUserProvider.
        Setup(u => u.CreateUser(Is.Any<User>(), ""))
        .Returns(new UserResponseObject { uid = "123", uri = userUri }).Verifiable();

     var userProvider = mockUserProvider.Object.CreateUser(Is.Any<User>(), "");

     mockUserProvider.Verify(u => u.CreateUser(Is.Any<User>(), ""));
}
链接地址: http://www.djcxy.com/p/54063.html

上一篇: Mock Abstract class using Moq

下一篇: Mocking using Moq in c#