这就是我在代码中所拥有的:
function myMethod()
{
foreach(var file in files)
{
if (noMatch)
{
//
SendEmailAndStopProcessing();
continue;
}
doSomething();
}
}
我有一个csv文件,它有多行,如果与db值匹配,我会处理它们。
我想创建一个单元测试,确认如果找到noMatch,那么将发送电子邮件并且doSomething将不会被执行。我在这里没有例外,因为没有必要,它通过发送电子邮件来处理(这些是业务规则)。但是,我需要创建一个单元测试来确认是否处理了这种情况。我该怎么处理?如果有异常,我会在我的测试方法中添加预期异常的属性,但由于没有,我被卡住了。
答案 0 :(得分:1)
在SendEmailAndStopProcessing()中发送电子邮件的任何功能都应该被拉出到一个接口(IEmailSender或其他东西),允许你通过你的类的构造函数注入该接口。
一旦你有了这个,你可以使用Moq或其他一些模拟框架,用一个实际上不会发送电子邮件的存根替换IEmailSender实现。通过这些,您通常可以对方法的调用次数进行断言(如果有的话),所以如果您使用Moq(例如),则可以这样做。
emailMock.Verify(x => x.SendEmail(),Times.Once)
如果未调用SendEmail,哪个会失败。你也可以为你的OrSomething方法做类似的事情。
关键是将组件隔离到接口中,以便可以使用Liskov替换原则随意换出它们。
答案 1 :(得分:0)
正如Kritner所说:创建一个SendEmailAndStopProcessing
的模拟并计算它被调用的频率。这当然假设SendEmailAndStopProcessing
可以被模拟(方法可以从测试类访问,并且可以被覆盖)。
例如使用Moq:
using Moq;
// ARRANGE
var serviceMock = new Mock<MyService>();
serviceMock.Setup(s => s.SendEmailAndStopProcessing()).Verifiable();
// ACT: call myMethod()
// ASSERT
const int expectedNumberOfCalls = 1;
serviceMock.Verify(x => x.SendEmailAndStopProcessing(), Times.Exactly(expectedNumberOfCalls));