首页 > 解决方案 > Moq:验证重载方法的方法

问题描述

我正在实施一项测试来检查在service.

[Fact]
public async Task MailService_SendMailMime_WhenItsOk()
{
    //Arrange
    var message = new MimeMessage
    {
        Subject = "My test message",
        Body = new TextPart("html")
        {
            Text = "Test"
        }
    };
    message.From.Add(new MailboxAddress("Collection System", "noreply@myemail.com"));
    message.To.Add(new MailboxAddress("User", "to@myemail.com"));


    //Act
    await _mailService.SendMailMimeAsync(message);

    //Assert
    _mocker.GetMock<ISmtpClient>().Verify(r => r.SendAsync(message, It.IsAny<MailboxAddress>(), It.IsAny<IEnumerable<MailboxAddress>>(), CancellationToken.None, It.IsAny<ITransferProgress>()), Times.Never);
}

我要测试的方法:

public async Task SendMailMimeAsync(MimeMessage message)
{
    try
    {
        var smtpHost = "mysmpthost.com" ;

        using (_smtpClient)
        {
            await _smtpClient.ConnectAsync(smtpHost, 25, false);
            await _smtpClient.SendAsync(message);
        }

        _logger.LogInformation($"SMTP message sent to {message.To}");
    }
    catch (Exception ex)
    {
        _logger.LogInformation($"There was a error while sending a SMTP message to {message.To}");
    }
}

有了这个,我试图用它Verify()来检查该SendAsync()方法是否至少被调用了一次。然而,由于他有方法重载,我只是通过指出他从未被调用 ( Times.Never) 来成功测试。它_smtpClient是一类MailKit.Net.Smtp。在此链接中,您可以查看您的方法: http: //www.mimekit.net/docs/html/T_MailKit_Net_Smtp_SmtpClient.htm

由于这种方法有几种重载的可能性,我不知道如何最好地测试它。

标签: c#asp.net-coremockingmoq

解决方案


MailKit的接口IMailTransport定义了几个重载:SendAsync

Task SendAsync(
      MimeMessage message,
      CancellationToken cancellationToken = default (CancellationToken),
      ITransferProgress progress = null);

Task SendAsync(
      MimeMessage message,
      MailboxAddress sender,
      IEnumerable<MailboxAddress> recipients,
      CancellationToken cancellationToken = default (CancellationToken),
      ITransferProgress progress = null);

Task SendAsync(
      FormatOptions options,
      MimeMessage message,
      CancellationToken cancellationToken = default (CancellationToken),
      ITransferProgress progress = null);

Task SendAsync(
      FormatOptions options,
      MimeMessage message,
      MailboxAddress sender,
      IEnumerable<MailboxAddress> recipients,
      CancellationToken cancellationToken = default (CancellationToken),
      ITransferProgress progress = null);

当您SendAsync这样调用时:SendAsync(message)
然后它将将此调用解析为以下重载:

Task SendAsync(
      MimeMessage message,
      CancellationToken cancellationToken = default (CancellationToken),
      ITransferProgress progress = null);

这意味着以下两个调用是等价的:

SendAsync(message);

SendAsync(message, default, default);

所以,你的Verify陈述应该是这样的:

[Fact]
public async Task MailService_SendMailMime_WhenItsOk()
{
    //Arrange
    var _smtpClientMock = new Mock<ISmtpClient>();
    var _mailService = new MailService(_smtpClientMock.Object);

    var message = new MimeMessage
    {
        Subject = "My test message",
        Body = new TextPart("html")
        {
            Text = "Test"
        }
    };

    //Act
    await _mailService.SendMailMimeAsync(message);

    //Assert
    _smtpClientMock.Verify(client => client.SendAsync(message, default, default), Times.Once);
}

推荐阅读