如何使用Moq验证此方法的输出

时间:2011-07-22 23:26:51

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

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

以下是我的Register ActionMethod中调用tempalte电子邮件的代码部分:

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

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

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

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

1 个答案:

答案 0 :(得分:0)

无需在没有返回的方法上使用Setup。由于外观Email只是一个数据结构,因此无需模拟它。除了它在控制器内部得到新功能之外,最好使用Send语法验证传入It.Is<>的对象是否具有我期望的属性。

[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个测试,你知道哪个条件会被满足。