如何从Mock的ISendgridService获取有效返回结果?
Hey there, let's break down why your test is returning a null result and fix it up!
The Problem with Your Current Code
Right now, you're creating a Mock<Func<SendGrid.Response>> and using its Invoke method to set the return value for SendAsync. The issue here is that this Func mock defaults to returning null—so when your test runs, result ends up being null too. Plus, wrapping the Response in a Func is totally unnecessary here.
The Fix: Directly Mock or Create a SendGrid.Response
We can simplify this by either creating a concrete SendGrid.Response instance (if the class allows it) or mocking the Response (if you need to control its behavior/properties). Here's how to adjust your test:
[TestMethod] public async Task SendEmailTest() { // 准备 var mockSendgrid = new Mock<ISendgridService>(); // Option 1: Create a concrete Response instance (works if the constructor is accessible) var validResponse = new SendGrid.Response(HttpStatusCode.OK, content: null, headers: null); // Option 2: Mock the Response if you need to override properties/methods // var mockResponse = new Mock<SendGrid.Response>(); // mockResponse.Setup(r => r.IsSuccessStatusCode).Returns(true); // Correctly set up the SendAsync method to return our valid response mockSendgrid.Setup(s => s.SendAsync(It.IsAny<IEmailMessage>())) .ReturnsAsync(validResponse); // Use mockResponse.Object if you went with Option 2 var emailMessage = _builder.CreateNew<EmailMessage>() .With(e => e.From = _sendgridConfiguration.SenderEmail) .With(e => e.FromName = _sendgridConfiguration.SenderName) .With(e => e.To = Faker.Internet.Email()) .Build(); // 执行 var result = await mockSendgrid.Object.SendAsync(emailMessage); // 断言:Now result is no longer null! Assert.IsNotNull(result); // Add more assertions based on your needs, e.g.: Assert.IsTrue(result.IsSuccessStatusCode); }
Bonus: Verify the Method Was Called
If you want to make sure SendAsync was actually invoked with the right email message, add this verification at the end of your test:
mockSendgrid.Verify(s => s.SendAsync(It.Is<IEmailMessage>(msg => msg.To == emailMessage.To)), Times.Once);
This checks that the method was called exactly once with an email message matching the To address you created.
内容的提问来源于stack exchange,提问作者Adam Mendoza

