Moq - 如何在开始测试的方法中模拟方法的结果

时间:2011-01-25 11:52:56

标签: unit-testing methods moq

并提前感谢您的任何和所有帮助。

我有一个方法,我正在尝试测试。

在此方法中是对UserMembership.Validate()的调用 //自定义覆盖,但代码尚未生效,超出了测试范围。

因此我想模拟(使用moq)返回结果,以便方法的实际测试可以成功。

这是代码

public LoginResponse Login(LoginRequest request)
{
    var response = new LoginResponse(request.RequestId);

    // Validate client tag and access token
    if (!ValidateRequest(request, response, Validate.ClientTag | Validate.AccessToken))
        return response;

    if (!UserMembership.ValidateUser(request.UserName, request.Password))
    {
        response.Acknowledge = AcknowledgeType.Failure;
        response.Messages = "Invalid username and/or password.";
        //response.MessageCode = -4;
        return response;
    }

    _userName = request.UserName;

    return response;
}

所以,我的测试是针对LoginResponse(),但我想将UserMembership返回值(bool)'伪造'为真......

很简单,我很确定你们。

TIA,休。

2 个答案:

答案 0 :(得分:0)

我认为在这种情况下模拟UserMembership的唯一方法(假设它不是属性)是使用IoC框架,如Castle WindsorNinject。当您使用IoC容器时,您会将对UserMembership的调用重构为接口(IUserMembership)并使用容器来提供实现:

if (Container.Resolve<IUserMembership>().ValidateUser(request.UserName, request.Password))

然后在单元测试安装程序中,您将IUserMembership的实现注册为模拟对象:

var mock = new Mock<IUserMembership>();
Container.Register<IUserMemberhip>().Instance(mock.Object);

您还必须创建一个生产实现。如果这是标准的UserMembership类,则此实现可能除了UserMembership之外什么都不做。虽然,还有其他方法来模仿这种鸭子打字。

答案 1 :(得分:0)

你可能会将你的问题重新命名为“你如何在99%的时间里使用模拟框架进行单元测试”,因为你正确地做到了这一点 - 这是一种非常典型的用法。

您将要从UserMembership类中提取接口(在类中单击鼠标右键,选择“refactor”,然后“提取接口”。),然后使用Moq创建该接口的模拟实例以供在其中使用你的考试。然后,您可以使用Moq“设置”该模拟的行为,以便在测试期间执行您想要的任何操作。语法如下所示:

var userMembershipMock = new Mock<IUserMembership>();
userMembershipMock.Setup(m=> m.ValidateUser(It.Is<string>(str=> str == "myUserName"), It.Is<string>(str=> str == "myPassword"))).Returns(true);

然后你会创建你的类的一个新实例,传入你的IUserMembership的模拟实例(但是因为你将使你的类的构造函数接受一个接口类型的参数,你的类将不关心你是否正在传递它是模拟或实际的UserMembership实例

 MyClass myClass = new MyClass(userMembershipMock.Object);

之后您可以开始实际测试MyClass的行为:

var request = new LoginRequest { UserName = "myUserName", Password = "myPassword" };
LoginResponse response = myClass.Login(request);

然后你可以断言你班级的反应是你所期望的:

Assert.AreEqual(AcknowledgeType.Success, response.Acknowledge);

或者您可以验证您的模拟方法(或属性)是否按预期调用:

userMembershipMock.Verify(m=> m.ValidateUser(It.Is<string>(str=> str == "myUserName"), It.Is<string>(str=> str == "myPassword")), Times.Once());

等等。

Moq quick start page是一种单页阅读,可以教你99%的使用它需要知道的一切。