C# 已处理异常的单元测试

C# 已处理异常的单元测试,c#,unit-testing,C#,Unit Testing,这就是我的代码: function myMethod() { foreach(var file in files) { if (noMatch) { // SendEmailAndStopProcessing(); continue; } doSomething(); } } 我有一个有多行的csv文件,如果与db值匹配,我会处理它们

这就是我的代码:

function myMethod()
{
    foreach(var file in files)
    {
        if (noMatch)
        {
            //
            SendEmailAndStopProcessing();
            continue;
        }
        doSomething();
    }
}
我有一个有多行的csv文件,如果与db值匹配,我会处理它们


我想创建一个单元测试,确认如果发现noMatch,那么将发送电子邮件,并且不会执行doSomething。我这里没有例外,因为没有必要这样做,它是通过发送电子邮件来处理的(这些是商业规则)。但是,我需要创建一个单元测试来确认这个案例是否得到了处理。我该怎么处理?如果有异常,我会在我的测试方法中添加预期异常的属性,但因为没有,我被卡住了。

正如Kritner所说:创建一个模拟的
sendmailandstopprocessing
,并计算调用它的频率。当然,这假设
sendmailandstopprocessing
可以被模拟(方法可以从测试类访问,并且可以被重写)

例如,使用:

使用Moq;
//安排
var serviceMock=new Mock();
serviceMock.Setup(s=>s.SendEmailAndStoppProcessing()).Verifiable();
//动作:调用myMethod()
//断言
const int expectedNumberOfCalls=1;
验证(x=>x.sendmailandstopprocessing(),Times.justice(expectedNumberOfCalls));

应该将SendEmailAndStoppProcessing()中发送电子邮件的任何功能拉入一个接口(IEmailSender或其他什么),允许您通过类的构造函数将该接口插入

一旦你做到了这一点,你就可以使用Moq或其他模拟框架,用一个实际上不会发送电子邮件的存根来代替iemailssender实现。有了这些,您通常可以断言一个方法被调用了多少次(如果有的话),所以如果您使用Moq(例如),您可以这样做

emailMock.Verify(x=>x.sendmail(),Times.Once)

如果您的SendEmail未被调用,则会失败。你也可以为你的或其他方法做类似的事情


关键是将组件隔离到接口中,以便可以使用Liskov替换原则随意替换它们。

“…并且不会执行
doSomething
”?这永远不会发生。您缺少
返回
其他
语句。什么是
noMatch
?如何确定?只要您的“文件”能够以某种方式进行操作,并且您的
发送电子邮件和停止处理
doSomething
是:
虚拟的
,或者更好,一个单独的可注入服务,可以根据您对
noMatch
结果的模拟进行模拟和验证。还有@RenéVogt所说的:D@Ren我错过了一个继续的声明,抱歉。我编辑了代码。@Kritner如果我分析文件中的行并将它们与db中的某些值进行比较,它们应该是相同的。如果不是这样,我会停止处理文件,并向管理员发送电子邮件通知他更改文件。您想停止处理所有文件,还是仅处理当前文件?此时,您正在停止当前文件。
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));