我真的很难过。
我有一个发送电子邮件通知的网络应用程序。
这是一个包含发送如下电子邮件的基本方法的类:
MailMessage email = new MailMessage();
email.To.Add("xxx@gmail.com");
email.Subject = "Test";
email.Body = "t";
SmtpClient client = new SmtpClient();
client.Send(email);
但是我有一个名为NotificatorService的服务验证了一些逻辑,因为这只是一个“额外”,这个服务的方法是在一个新的线程中调用的。我的工作是这样的:
public void NotifyMembers(NotificatorClientDTO clientDto) {
if(clientDto == null)
throw new ArgumentNullException("clientDto");
Thread t = new Thread(
() => {
// go to database, verify business rules, etc...
// At the end if it is ok, invoke the method that sends a email
}
t.Start()
}
如果我创建一个单元测试来实例化NotificatorService并使用某些数据调用notifyMembers,那么代码将抛出异常但仅当我在一个单独的线程中执行时。
我创建的主题是在foregronnd设置的,所以系统不会破坏我的过程。
异常消息是:
SmtpException:无法计算表达式,因为代码已优化或本机框位于调用堆栈之上
我走到2个内部异常,我看到了这个
_message“线程正在中止。”串
为什么会这样? 导致线程中止的原因是什么?
答案 0 :(得分:2)
将您的单元测试更改为IMailService
或类似的依赖项。然后,您的Web应用程序单元测试不需要在发送电子邮件方面做任何真正的 - 它可以使用假冒或模拟。
然后你需要创建一个IMailService
的生产实现 - 并且单元测试 可能仍然具有挑战性,但至少你只能 对测试邮件处理感兴趣,这意味着您可以稍微改变约束。
您可以为线程创建方面做同样的事情。基本上,尝试从您想要测试的真实逻辑中分离出代码的“讨厌的位”(与邮件服务和线程交互)。
答案 1 :(得分:1)
这看起来像是集成测试而非单元测试,正如您在标题中所指定的那样。
尝试将App.config添加到包含以下内容的Tests.Assembly项目中,看看它是否有帮助:(使用ApartmentState=MTA and ApartmentState=STA
)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="NUnit">
<section name="TestRunner" type="System.Configuration.NameValueSectionHandler"/>
</sectionGroup>
</configSections>
<NUnit>
<TestRunner>
<add key="ApartmentState" value="STA" />
</TestRunner>
</NUnit>
</configuration>