【问题标题】:Mocks to verify interaction模拟以验证交互
【发布时间】:2011-06-30 09:09:10
【问题描述】:

通常,当我需要模拟一个类进行测试时,我会使用 Rhino Mocks 之类的库。在这里,我有一个名为 MyService 的类,它需要 IEmailSender

public class MyService
{
    private readonly IEmailSender sender;

    public MyService(IEmailSender sender)
    {
        this.sender = sender;
    }

    public void Start()
    {
        this.sender.SendEmail();
    }
}

如果我需要测试这两个对象之间的交互,我的测试应该是这样的:

[TestMethod]
public void Start_Test_Using_Rhino_Mocks()
{
    IEmailSender emailSender = MockRepository.GenerateMock<IEmailSender>();

    MyService service = new MyService(emailSender);
    service.Start();

    emailSender.AssertWasCalled
        (
            x => x.SendEmail(),
            c => c.Repeat.Once()
        );
}

在上面的测试中,我使用 Rhino Mocks 来生成模拟并断言 SendEmail() 方法被调用了一次。

但是如果我不能使用 Rhino Mocks 而必须手动创建模拟呢?

public class MockEmailSender : IEmailSender
{
    public void SendEmail()
    {
    }
}

[TestMethod]
public void Start_Test_Using_Manual_Mocks()
{
    MockEmailSender emailSender = new MockEmailSender();

    MyService service = new MyService(emailSender);
    service.Start();

    // How do I test the interaction?
}

使用我手动创建的模拟,我将如何验证 SendEmail() 方法是否被调用?我可以将我的断言放在模拟的 SendEmail() 方法中,但这会使测试难以理解,因为当我查看测试时我不会立即看到发生了什么。

【问题讨论】:

    标签: c# .net unit-testing mocking rhino-mocks


    【解决方案1】:

    一个非常简单的解决方案是让您的手动模拟只是一个状态持有者,并为每个方法的调用提供计数器。但它很脆弱......

    public class MockEmailSender : IEmailSender
    {
        public int SendCount = 0;
    
        public void SendMail(...)
        {
            SendCount++;
        }
    
        // ... other IEmailSender methods ...
    }
    

    然后只需在调用方法后查询 SendCount,并确保它是 == 1。

    请记住,Rhino Mocks 正在为您动态创建它 - 如果您手动执行此操作,则必须在编译前手动对界面更改做出反应。

    【讨论】:

      【解决方案2】:

      我认为除了在“SendEmail()”中设置一个 标志,并通过 MockEmailSender 的新方法(如“sendMailWasInvoked()”或其他方法)从测试中检查该标志之外,您别无选择像这样(这实际上是一种“验证”)。 您可以扩展它来计算调用次数、参数...

      【讨论】:

        【解决方案3】:

        我建议不要创建任何手动 Mocks(因为如果您向接口添加新方法,它会损坏)。

        如果你真的必须这样做,当你在你的 MockEmailSender 中公开一些计数器/布尔值时,你可以稍后断言它。

        Assert.IsTrue(emailSender.IsCalled)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-14
          • 1970-01-01
          • 2020-03-26
          • 1970-01-01
          • 2023-02-15
          • 1970-01-01
          • 1970-01-01
          • 2019-09-17
          相关资源
          最近更新 更多