等待单元测试中的asyncrhonous事件引发事件

use*_*661 6 c# events unit-testing asynchronous

我正在尝试从单元测试中单独测试事件SmtpClient.SendCompleted的测试,并且我遇到了一个烦人的问题,测试在事件实际触发之前继续处理,终止应用程序而不实际进入事件.那么,想象下面的代码:

[TestClass]
public class emailTest
{
    public bool sentEmail = false;

    [TestMethod]
    public void sendEmail()
    {
        SmtpClient smtp = new SmtpClient("smtpserver");
        smtp.SendCompleted += delegate(Object sender, System.ComponentModel.AsyncCompletedEventArgs e) { sentEmail = true; };
        MailMessage mm = new MailMessage("from@address.com", "to@address.com", "test subject", "test body");
        smtp.SendAsync(mm, "test");
        Assert.IsTrue(sentEmail);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我手动插入这样的延迟,则此测试失败...

[TestClass]
public class emailTest
{
    public bool sentEmail = false;

    [TestMethod]
    public void sendEmail()
    {
        SmtpClient smtp = new SmtpClient("smtpserver");
        smtp.SendCompleted += delegate(Object sender, System.ComponentModel.AsyncCompletedEventArgs e) { sentEmail = true; };
        MailMessage mm = new MailMessage("from@address.com", "to@address.com", "test subject", "test body");
        smtp.SendAsync(mm, "test");
        System.Threading.Thread.Sleep(50000); // Manual Delay
        Assert.IsTrue(sentEmail);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后测试通过.

让方法等待smtp.SendAsync作为一个任务似乎没有实际工作,因为我实际上并没有等待SendAsync,我正在尝试等待SendCompleted完成执行,然后继续进行其余的测试,而且我不太清楚该怎么做.

由于时间原因,我只需要等待Se​​ndCompleted完成处理的最短时间.

我做了很多搜索,似乎无法找到解决这个特定问题的任何东西.

快速编辑:在所有情况下,电子邮件成功发送,只有测试失败.

dca*_*tro 9

好吧,我必须承认,SendCompleted只有在SendAsync返回后触发的事实听起来有点奇怪......它确实使单元测试变得更难.

但是如果你想等待最少的时间,你将不得不引入同步原语.AutoResetEvent听起来非常适合这种情况.

// Arrange
var are = new AutoResetEvent(false);

var smtp = new SmtpClient("smtpserver");
smtp.SendCompleted += (s, e) => { are.Set(); };
var mm = new MailMessage("from@address.com", "to@address.com", "test subject", "test body");

// Act
smtp.SendAsync(mm, "test");

// Assert
var wasSignaled = are.WaitOne(timeout: TimeSpan.FromSeconds(1));
Assert.True(wasSignaled);
Run Code Online (Sandbox Code Playgroud)

  • @ user3657661你的意思是"它不起作用".这无助于推动对话.这个问题已经回答了两次:在这个答案(有效)和我申请的副本中. (2认同)
  • 在这段代码中,超时设置为1秒可能太短.如果您花时间*了解它正在做什么,您可以将超时更改为无穷大.您还没有回复重复. (2认同)