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

发布于 2024-10-14 07:46:17 字数 908 浏览 3 评论 0 原文

并提前感谢您提供的所有帮助。

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

在此方法中调用 UserMembership.Validate() //自定义覆盖,但代码尚未运行并且超出了测试范围。

因此,我想模拟(使用最小起订量)返回结果,以便该方法的实际测试能够成功。

这是代码

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)“伪造”为 true...

我相信对你们来说足够简单。

蒂亚,休。

and thank you in advance for any and all your assistance.

I have a method that I'm trying to test.

Within this method is a call to UserMembership.Validate()
//custom override but the code isn't functional yet and is outside the scope of the test.

I want to therefore mock (using moq) the return result so that the actual test of the method can succeed.

Here is the code

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;
}

So, my test is for LoginResponse() but I want to 'fake' the UserMembership return value (bool) to true...

Simple enough I'm sure for you guys.

TIA, Hugh.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我家小可爱 2024-10-21 07:46:17

您可能可以将您的问题重新命名为“如何在 99% 的情况下使用模拟框架进行单元测试”,因为您正朝着这样做的方向前进——这是一种非常典型的用法。

您需要从 UserMembership 类中提取一个接口(在类内右键单击,选择“重构”,然后选择“提取接口”),然后使用 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 快速启动页面。有点像一页纸的阅读,可以教你 99% 使用它所需知道的一切。

You could probably re-title your question to "How do you use a mocking framework with unit testing 99% of the time," because you're right on track for doing just that - a very typical usage.

You're going to want to extract an interface from your UserMembership class (right click inside the class, select "refactor" and then "extract interface."), then use Moq to create mock instances of that interface for use within your tests. Then you can use Moq to "setup" the behavior of that mock to do anything you want it to during your test. The syntax would look like this:

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

Then you would create a new instance of your class, passing in your mock instance of IUserMembership (but since you'll make your class's constructor takes an argument of the interface type, your class won't care whether you're passing it a mock or an actual UserMembership instance

 MyClass myClass = new MyClass(userMembershipMock.Object);

after which you could begin actually testing the behavior of your MyClass:

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

And then you can assert that your class's response is what you expect:

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

or you can verify that your mock's method (or property) was invoked as you expected:

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

and so on.

The Moq quick start page is kind of sort of a one-page read, and can teach you 99% of everything that you need to know to use it.

已下线请稍等 2024-10-21 07:46:17

在这种情况下,我能想到的模拟 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 之外什么也不做。尽管如此,还有其他方法可以模仿这种鸭子类型。

The only way I can think of to mock UserMembership in this case (assuming it's not a property) is to use an IoC framework like Castle Windsor or Ninject. When you use an IoC container you would refactor your calls to UserMembership into an interface (IUserMembership) and use the container to provide an implementation:

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

Then in your unit test Setup you would register the implementation of IUserMembership to be the mock object:

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

You would have to also create a production implementation. If this is the standard UserMembership class, this implementation will probably do nothing other than UserMembership. Although, there are other ways to mimic this kind of duck typing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文