![](/img/trans.png)
[英]How to Mock a method in a class that inherited Abstract class using MsTest Moq
[英]Mock Abstract class using Moq
我有下面的抽象类和测试方法。 使用“最小起订量”,我得到以下错误:
我的抽象课程:
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;
}
除了依赖一个确切的实例(即避免比较两个引用),您还可以检查任何实例:
mockUserProvider.Verify(u => u.CreateUser(It.IsAny<UserRequestObject>(),
It.IsAny<string>()), Times.Once);
或者,最好是满足特定条件的实例(假设GetUserRequestObject()
的属性Name
设置为Bob
)
mockUserProvider.Verify(u => u.CreateUser(
It.Is<UserRequestObject>(x => x.Name == "Bob"),
It.Is<string>(s => s == "")));
您的GetUserRequestObject()
可能会返回2个不同的UserRequestObject
对象实例。
确保使用相同的实例设置期望并通过调用对其进行验证。 (否则,在设置期望值时使用It.IsAny<UserRequestObject>
。
Moq会检查对您的对象的引用。 您应该验证并将设置方法中使用的对象传递给它:
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>(), ""));
}
非常简单-您所做的一切正确,但您的验证错误。
您正在创建一个新的用户提供程序,但尚未指定要创建的提供程序。
您需要使用它而不是空白:
mockUserProvider.
Setup(u => u.CreateUser(new user, ""))
.Returns(new UserResponseObject { uid = "123", uri = userUri }).Verifiable();
由此,您需要在检查新用户时纠正您的verify语句:
mockUserProvider.Verify(u => u.CreateUser(It.IsAny<User>()));
这意味着您实际上是在检查是否已创建用户实体,而在您测试期望的结果之前。 就像按照这种方式测试某些东西一样-假设您要创建一件艺术品,然后对其进行计划和设置(模拟)。 但您尚不知道将要创建的内容-因此在验证中,您需要创建艺术品,并且需要验证该艺术品是某种艺术品,而不仅要验证该方法是否已运行,因为它会返回您未检查的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.