【问题标题】:How can I verify the output of this method using Moq如何使用 Moq 验证此方法的输出
【发布时间】:2011-07-22 23:26:50
【问题描述】:

我有一个 MVC3 应用程序,并且在 AccountController 上有一个注册 ActionMethod。当用户注册时,我希望它通过电子邮件向他们发送用户详细信息。我正在使用Postal(第一次)并且想要运行一个单元测试来验证 Send 方法被调用并且我已经调用了 Register 电子邮件模板。

这是我的注册操作方法中调用电子邮件模板的代码部分:

dynamic email = new Email("Register");
email.To = model.Email;
_emailService.Send(email);

_emailService 是 IEmailService 类型。我正在使用 Moq 并且知道如何验证方法是否已被调用,但在这种情况下,我将一个电子邮件对象传递给 Send。所以我不知道我是否创建了一个 Mock 或者注册控制器上使用的 Email 对象是否是我应该测试的。我也不确定测试电子邮件“输出”或至少验证 Views/Emails 文件夹中的“注册”模板是否被调用的最佳方法。到目前为止,这是我的测试:

    [TestMethod]
    public void register_post_success_sends_email_with_account_details()
    {
        // Arrange
        // fakeMembers contains a List<Member> repository of 5 fake Members which I 
        // use to ensure the Register completes and then steps into the code 
        // that calls the email code authentication code
        FakeMembers fakeMembers = new FakeMembers();
        _mockMemberRepository.Setup(x => x.GetMembers()).Returns(fakeMembers.Members);
        _mockEmailService.Setup(e => e.Send(?? what do I place here??));
        // set up of emailService.Send is a void method so do I just not use Returns?

        //// Arrange
        Member model = new Member()
        {
            Email = "member6@mydomain.com",
            Password = "test123",
            ConfirmPassword = "test123"
        };
        Mock<Email> mockEmail = new Mock<Email>();
        // Act
        var result = _controller.Register(model);

        // Assert
        // Do I use a mockEmail.Object here? I want to test the Email called on the 
        // Register ActionMethod?

        // Test Send method was called ONCE
        _mockEmailService.Verify(e => e.Send(mockEmail.Object), Times.Once());

        //Test either the output of the Email that was sent OR check that it was the
        //Register email template that was called
    }

我希望我已经足够简洁,有人可以提供帮助

【问题讨论】:

    标签: unit-testing asp.net-mvc-3 moq


    【解决方案1】:

    无需在没有返回的方法上使用Setup。因为看起来Email 只是一个数据结构,所以没有必要模拟它。此外,由于它是在控制器内部更新的,因此最好使用 It.Is&lt;&gt; 语法验证传递给 Send 的对象是否具有我期望的属性。

    [TestMethod]
    public void register_post_success_sends_email_with_account_details()
    {
        //// Arrange
        FakeMembers fakeMembers = new FakeMembers();
        _mockMemberRepository.Setup(x => x.GetMembers()).Returns(fakeMembers.Members);
    
        Member model = new Member()
        {
            Email = "member6@mydomain.com",
            Password = "test123",
            ConfirmPassword = "test123"
        };
    
        //Act
        var result = _controller.Register(model);
    
        //Assert
        _mockEmailService.Verify(e => e.Send(It.Is<Email>(email =>
               {
                   return email.To == model.Email;  // you can add more here such as the body etc
               }), Times.Once())
    
      //Test either the output of the Email that was sent OR check that it was the
      //Register email template that was called
    

    至于这部分,我将分为 2 个测试,您知道将满足哪个条件。

    【讨论】:

      猜你喜欢
      • 2012-02-26
      • 1970-01-01
      • 2013-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-03
      • 1970-01-01
      相关资源
      最近更新 更多