【发布时间】:2015-10-22 02:17:27
【问题描述】:
当方法本身在传递给Task.Run 的委托中调用时,如何验证在模拟上调用了方法?到 mock.Verify 被调用时,Task 仍未执行。
我在mock.Verify 之前尝试过await Task.Delay,但这似乎让测试运行程序挂起。
使用Task.Run的原因是为了卸载逻辑,防止攻击者在执行的时候能够区分系统中是否存在邮件地址。
using System.Threading.Tasks;
using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
namespace AsyncTesting
{
class MyController : Controller
{
public IEmailService EmailService { get; set; }
public MyController(IEmailService emailService)
{
EmailService = emailService;
}
public ViewResult BeginPasswordReset(string emailAddress)
{
BeginPasswordResetAsync(emailAddress);
return View();
}
private Task BeginPasswordResetAsync(string emailAddress)
{
return Task.Run(delegate
{
EmailService.Send(emailAddress);
});
}
}
internal interface IEmailService
{
void Send(string emailAddress);
}
internal class MyControllerTests
{
[TestMethod]
public void BeginPasswordReset_SendsEmail()
{
var mockEmailService = new Mock<IEmailService>();
var controller = new MyController(mockEmailService.Object);
const string emailAddress = "email@domain.com";
controller.BeginPasswordReset(emailAddress);
mockEmailService.Verify(es=>es.Send(emailAddress));
}
}
}
【问题讨论】:
-
我不确定 MSTest 但是使用 NUnit 你可以有一个异步测试方法并等待
BeginPasswordResetAsync方法。该任务将在等待后完成。查看使用 MSTest 进行的异步测试。 -
The reason for using Task.Run...抱歉,但这是在您的应用程序中引入这样的故障点的糟糕理由。Task.Run在 ASP.NET 上非常危险;至少,使用HostingEnvironment.QueueBackgroundWorkItem。 -
谢谢@StephenCleary,我会仔细阅读您对blog.stephencleary.com/2013/10/…的主题的讨论
-
@RDay:我在fire and forget 上的帖子更直接适用于这里。
标签: c# unit-testing moq mstest