繁体   English   中英

单元测试/如何断言非模拟方法被称为/ C#/ Rhino Mocks / NUnit

[英]Unit testing/How to assert a non-mocked method was called/C#/Rhino Mocks/NUnit

我有一个MailService,允许我发送实现以下接口的电子邮件。

public interface IMailService
  {
    bool SendRegisteringEmail(RegisterModel registerModel);
    bool SendMail(MailMessage mailMessage);
    MailMessage CreateRegisteringMailMessage(RegisterModel registerModel);

    IAppSettingsRepository AppSettingsRepository { get; set; }

    ISmtpClient SmtpClient { get; set; }
  }

函数SendRegisteringEmail应该调用CreateRegisteringMailMessage,然后将返回MailMessage交给SendMail函数,而SendRegisteringEmail应该返回SendMail的返回布尔值。

我正在使用NUnit和Rhino Mocks进行测试,我是测试的新手(1周),并且正在练习TDD(至少我尝试过)。 我的问题是我不知道如何在我调用SendRegisteringEmail时断言CreateRegisteringMailMessage已被调用,因为MailService不是模拟对象。 这是我的测试:

[Test]
public void SendRegisteringEmail_ShouldCallCreateRegisteringMailMessage()
{
  //Arrange
  //MailMessage mailMessage = new MailMessage();
  IMailService mailService = new MailService { AppSettingsRepository = CreateAppSettingsMockReposotory() };
  //ISmtpClient smtpClientStub = MockRepository.GenerateStub<ISmtpClient>();
  //mailService.SmtpClient = smtpClientStub;
  //smtpClientStub.Stub(f => f.Send(mailMessage)).Return(true);


  //Act
  mailService.SendRegisteringEmail(ValidRegisterModel);

  //Assert
  mailService.AssertWasCalled(f => f.CreateRegisteringMailMessage(ValidRegisterModel));
}

启动测试时收到以下错误:FtpWeb.Tests.MailServiceTests.SendRegisteringEmail_ShouldCallCreateRegisteringMailMessage:System.InvalidOperationException:对象'FtpWeb.Models.MailService'不是模拟对象。

我了解为什么会收到此错误,但是现在如何测试我的通话。 由于它是同一对象,因此我无法对其进行测试。 如果有人可以给我一些解决方法。

谢谢。

我不确定您是否应该测试是否调用了CreateRegisteringMailMessage 您应该只检查调用SendRegisteringEmail结果 这与您的MailService实现有什么关系? 大概会对其他服务产生影响-因此进行测试。

这将是一个奇怪的接口设计,该设计坚持要求调用一个方法将需要在接口中调用另一个方法-例如,通常您可能使两个方法都调用一个私有的通用方法。

方法CreateRegisteringMailMessageSendMail抽象级别似乎低于SendRegisteringEmail抽象级别。 您可以考虑创建一个包含SendRegisteringEmail的更高级别的类,并且该类将使用IMailService,您可以照常进行模拟和断言。

如果不是第一种解决方案,那么您应该将SendRegisteringEmail作为一个整体来对待,因此,有效的方法是您必须在一个测试中测试CreateRegisteringMailMessageSendMail副作用(有点代码味道,因此我建议提取另一个间接级别)-参见乔恩的答案。

这通常在被测类中被称为“传感”:您必须找到一种方法来判断是否已调用方法。 每个人都应该在《 用传统代码有效工作 》一书中很好地论述了这些事情(免责声明:我与这本书的作者没有从属关系,我只是认为这是一本好书)。

CreateRegisteringMailMessage方法有什么作用? 它会影响在调用过程中传递的RegisterModel实例的内容吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM