rad*_*scu 10 c# unit-testing exception-handling exception c#-4.0
如何模拟C#单元测试中抛出的异常?
我希望能够100%覆盖我的代码,但我无法使用可能发生的异常来测试代码.例如,我无法模拟可能发生的功率损失.
例如:
public void MyMethod()
{
try
{
...
}
catch(OutOfMemoryException e)
{
...
}
catch(RandomErrorFromDatabaseLayer e)
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够模拟此方法中的任何类型的异常,并且应该被捕获.
在这件事上有没有可以帮助我的图书馆?
编辑1:完成我向Moq询问的任何帮助?
您需要创建一个模拟对象,代表可以抛出这些异常的真实对象.然后你可以创建像这样的测试:
public void ExampleMethod()
{
throw new OutOfMemoryException();
}
Run Code Online (Sandbox Code Playgroud)
如果您正在使用依赖注入框架,则可以更轻松地使用模拟代码替换实际代码.
你需要的是存根 - 一个模拟你的代码的某些条件的对象.出于测试目的,通常用stub(或其他类型的伪对象)替换实际对象实现.在您的情况下,请考虑:
public class MyClass
{
private IDataProvider dataProvider;
public void MyMethod()
{
try
{
this.dataProvider.GetData();
}
catch (OutOfMemoryException)
{
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您正在测试的类应该可以在某个级别进行配置 - 这样您DataProvider在测试时可以轻松地用存根/伪造的实际实现取代(就像您说的那样,您不想破坏您的数据库 - 没人想要!).这可以通过例如构造器注入(或实际上,任何其他依赖注入技术)来实现.
那么你的测试是微不足道的(一些需要在测试异常时进行测试):
[Test]
public void MyMethod_DataProviderThrowsOutOfMemoryException_LogsError()
{
var dataProviderMock = new Mock<IDataProvider>();
dataProviderMock
.Setup(dp => dp.GetData())
.Throws<OutOfMemoryException>();
var myClass = new MyClass(dataProviderMock);
myClass.MyMethod();
// assert whatever needs to be checked
}
Run Code Online (Sandbox Code Playgroud)