Mock Abstract class using Moq
I have the below abstract class and test method. Using "Moq" i got the below error:
My Abstact class :
public abstract class UserProvider
{
public abstract UserResponseObject CreateUser(UserRequestObject request, string userUrl);
public abstract bool IsUserExist(UserRequestObject request, string userUrl);
}
Test Class :
[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(), ""));
}
Error Message :
Moq.MockException: Expected invocation on the mock at least once, but was never performed: u => u.CreateUser(.GetUserRequestObject(), "")
Anyone please explain, why i got this message and how to resolve it?
The reason why you are getting this error, is because you are setting the expectation on a specific instance of an object:
mockUserProvider.Verify(u => u.CreateUser(GetUserRequestObject(), ""));
This will depend heavily on how the method is implemented. eg This implementation of GetUserRequestObject()
will create a new instance on each call, and the verify will always fail:
private UserRequestObject GetUserRequestObject()
{
return new UserRequestObject();
}
Whereas returning the same instance for the setup and verify will succeed:
private UserRequestObject u = new UserRequestObject();
private UserRequestObject GetUserRequestObject()
{
return u;
}
Instead of being dependent on an exact instance (ie avoid comparing 2 references), you could instead either check for Any instance:
mockUserProvider.Verify(u => u.CreateUser(It.IsAny<UserRequestObject>(),
It.IsAny<string>()), Times.Once);
Or preferably, an instance which meets a specific criterion (Assuming that GetUserRequestObject()
has a property Name
which is set to Bob
)
mockUserProvider.Verify(u => u.CreateUser(
It.Is<UserRequestObject>(x => x.Name == "Bob"),
It.Is<string>(s => s == "")));
Your GetUserRequestObject()
might be returning 2 different instances of the UserRequestObject
object.
Ensure the same instance is used for both setting the expectations and verifying it via the call. (else, use It.IsAny<UserRequestObject>
while setting expectations.
Moq checks the reference to your object. You should verify and pass to it the same object that you used in setup method:
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, ""));
}
Alternatively you may check it for any object passed to method:
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/54064.html
上一篇: 模拟与Moq的懒惰界面
下一篇: 模拟使用Moq的抽象类