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

Unit testing 如何使用Moq验证此方法的输出,unit-testing,asp.net-mvc-3,moq,Unit Testing,Asp.net Mvc 3,Moq,我有一个MVC3应用程序,在AccountController上有一个Register ActionMethod。当用户注册时,我希望它通过电子邮件向他们发送其用户详细信息。我正在使用(第一次)并希望运行一个单元测试,以验证是否调用了Send方法以及是否调用了Register-email模板 下面是我的Register ActionMethod中调用电子邮件tempalte的代码部分: dynamic email = new Email("Register"); email.To = model

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

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

dynamic email = new Email("Register");
email.To = model.Email;
_emailService.Send(email);
_emailService属于IEmailService类型。我正在使用Moq,并且知道如何验证方法是否已被调用,但在本例中,我正在将一个Email对象传递给Send。所以我不知道我是否创建了一个Mock,或者注册控制器上使用的Email对象是否是我应该测试的对象。我也不确定测试电子邮件“输出”或至少验证是否调用了视图/电子邮件文件夹中的“注册”模板的最佳方法。以下是我目前的测试:

    [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
    }
[TestMethod]
公共无效注册\发布\成功\发送\电子邮件\包含\帐户\详细信息()
{
//安排
//fakeMembers包含一个包含5个伪造成员的列表存储库,我
//用于确保寄存器完成,然后进入代码
//这将调用电子邮件代码身份验证代码
FakeMembers FakeMembers=新的FakeMembers();
_mockMemberRepository.Setup(x=>x.GetMembers()).Returns(fakeMembers.Members);
_mockEmailService.Setup(e=>e.Send(??我在这里放置什么??);
//设置emailService.Send是一个无效方法,所以我不使用Returns吗?
////安排
成员模型=新成员()
{
电子邮件=”member6@mydomain.com",
Password=“test123”,
ConfirmPassword=“test123”
};
Mock mockEmail=new Mock();
//表演
var结果=_controller.Register(模型);
//断言
//我是否在此处使用mockEmail.Object?我想测试在
//注册操作方法?
//测试发送方法被调用一次
_验证(e=>e.Send(mockEmail.Object),Times.Once());
//测试发送的电子邮件的输出或检查它是否为
//注册调用的电子邮件模板
}

我希望我已经足够简洁,有人可以帮助我,不需要在一个没有回报的方法上使用
设置。从外观上看,电子邮件仅仅是一种数据结构,因此没有必要对其进行模拟。此外,由于它在控制器内部是新的,因此最好使用
it.is
语法验证传入
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