Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Moq误报:MoqException被程序try/catch逻辑捕获_C#_Unit Testing_Moq - Fatal编程技术网

C# Moq误报:MoqException被程序try/catch逻辑捕获

C# Moq误报:MoqException被程序try/catch逻辑捕获,c#,unit-testing,moq,C#,Unit Testing,Moq,我正在为一些遗留代码编写单元测试,遇到了一种情况,我的单元测试出现了误报。下面是一个简化的例子 如果我忘记为DoSomething设置一个实现,我希望下面的测试失败并出现一个MockException。但是,异常实际上是由业务逻辑中的try/catch捕获的,因此测试似乎通过了。VerifyAll同样不会导致失败,因为该方法已被“调用” 我发现了一个与这个问题相关的问题,但似乎没有回应 关于如何确保该测试有效,有什么想法吗 public class SUT { public ISyst

我正在为一些遗留代码编写单元测试,遇到了一种情况,我的单元测试出现了误报。下面是一个简化的例子

如果我忘记为DoSomething设置一个实现,我希望下面的测试失败并出现一个MockException。但是,异常实际上是由业务逻辑中的try/catch捕获的,因此测试似乎通过了。VerifyAll同样不会导致失败,因为该方法已被“调用”

我发现了一个与这个问题相关的问题,但似乎没有回应

关于如何确保该测试有效,有什么想法吗

public class SUT 
{
    public ISystem iSystem { get; set; } // complicated web service

    public void Foo()
    {
        try
        {
            iSystem .DoSomething();
        }
        catch (Exception ex)
        {
            //Report error
        }
    }
}

[TestClass]
public class Test
{
    [TestMethod]
    public void TestDoSomething()
    {
        var mr = new MockRepository(MockBehavior.Strict);
        var iSystem = mr.Create<ISystem>();
        var foo = new Foo { Interface = interface.Object };

        foo.DoSomething();

        mr.VerifyAll();
    }
}
公共类SUT
{
公共ISystem ISystem{get;set;}//复杂的web服务
公共图书馆
{
尝试
{
iSystem.DoSomething();
}
捕获(例外情况除外)
{
//报告错误
}
}
}
[测试类]
公开课考试
{
[测试方法]
公共void TestDoSomething()
{
var mr=新的MockRepository(MockBehavior.Strict);
var iSystem=mr.Create();
var foo=newfoo{Interface=Interface.Object};
foo.DoSomething();
VerifyAll先生();
}
}

您的单元测试应该隔离被测试的类,SUT通过记录(并接受)错误来正确运行-如果您想测试属于iSystem测试的抛出。如果检测到意外的错误日志调用,测试可能仍然会失败。

我认为这里的问题实际上与moq或测试无关,而更多的是设计/异常处理实践

我认为
Foo
的构造函数不是处理所有意外错误的合适位置

您可能希望出现意外异常,例如
OutOfMemoryException
StackOverflowException
和其他意外异常,以便冒泡到一个集中的位置,处理所有致命错误

通常,这将是:

  • 对于WPF:AppDomain.UnhandledException事件()
  • 对于命令行应用程序:未处理的ExceptionEventHandler()
  • 对于ASP.Net,global.asax()中的应用程序错误方法
底线是。为了解决您的问题,首先,编写一个全新的测试,在其中设置
DoSomething()
方法以引发异常

使用

mr.Setup(o=>o.DoSomething().Throws();
然后,断言实例化
Foo
不会吞噬
MyUnexpectedException
,而是实际抛出

这样做,您将被迫更改
catch
语句并使用更具体的类型(在catch块中使用
Exception
是一种非常糟糕的做法)

然后,通过更改体系结构,
MockException
,继承自
Exception
catch
块将不会处理它

mr.Setup(o => o.DoSomething().Throws<MyUnexpectedException>();