如何模拟SendGrid

问题描述 投票:0回答:2

我正在尝试为我编写的使用 SendGrid 发送电子邮件的方法编写单元测试。 我的方法是这样的:

public async Task SendEmail(TemplatedMailMessage emailMessage)
{
    if (String.IsNullOrWhiteSpace(emailMessage.Html) || String.IsNullOrWhiteSpace(emailMessage.From.ToString()) || !emailMessage.To.Any())
    {
        throw new Exception("Html, From or To is empty");
    }

    try
    {
        // Send the email
        await this.TransportWeb.DeliverAsync(emailMessage.GetSendGridMessage());
    }
    catch (Exception ex)
    {
        //do stuff
    }

    //log success
}

TransportWeb 是一个属性,它通过参数在我的构造函数中设置,以便我可以创建一个模拟对象。

public EmailManager(Web transportWeb = null)
{
    this.TransportWeb = transportWeb ?? SetupSendGrid();
}

在我的测试方法中,我尝试模拟 TransportWeb(SendGrid.Web 类型)属性:

    [TestMethod]
    public async Task SendEmail_ValidEmailTemplateAndNoParameters_EmailIsSent()
    {
        //ARRANGE
        var templatedMailmessage = new Mock<TemplatedMailMessage>();
        var transportWeb = new Mock<Web>();
        transportWeb.SetupAllProperties();
        transportWeb.Setup(x => x.DeliverAsync(It.IsAny<ISendGrid>()));
        var emailManager = new EmailManager(transportWeb.Object);

        //ACT
        await emailManager.Send(templatedMailmessage.Object);

        //ASSERT
        transportWeb.Verify(x => x.DeliverAsync(It.IsAny<ISendGrid>()), Times.Once());
    }

但是,我收到以下错误:

非虚拟(在 VB 中可重写)成员上的设置无效:x => x.DeliverAsync

有人知道我该如何解决这个问题吗?

c# unit-testing moq mstest sendgrid
2个回答
5
投票

好的,我修好了:)

您不应该使用 Web 类,而应该使用 ITransport 接口:

var transport = new Mock<ITransport>();
transport.SetupAllProperties();
transport.Setup(x => x.DeliverAsync(It.IsAny<SendGridMessage>())).ReturnsTask();

var em = new EmailManager(transport.Object);

我还使用了 Simon V 创建的 扩展方法


0
投票

如果您的测试只是想检查电子邮件是否已发送,那么您可以拥有自己的实现 ISendGridClient 的 TestSendGridClient。 唯一要实现的方法是 SendEmailAsync,它将电子邮件添加到内部集合中。

public List<string> emails = new List<string>();

public async Task<Response> SendEmailAsync(SendGridMessage msg, 
CancellationToken cancellationToken = default)
{
    emails.AddRange(msg.Personalizations[0].Tos.Select(x => x.Email));

    return await Task.FromResult(new Response(System.Net.HttpStatusCode.OK, null, null));
}

然后在测试中,您只需检查预期的电子邮件是否在电子邮件列表中。

© www.soinside.com 2019 - 2024. All rights reserved.