【发布时间】:2011-03-17 13:33:10
【问题描述】:
我刚开始进行单元测试,有一个场景我不知道如何解决,而且我的解决方案感觉不对。
我有一些代码可以做某事,如果它失败,即抛出异常,异常将被捕获并记录如下。
public T CreateTypedObjectInstance<T>()
{
T o = default(T);
try
{
o = Activator.CreateInstance<T>();
}
catch (Exception ex)
{
LogError(ex);
throw ex;
}
return o;
}
private void LogError(Exception ex)
{
if (logger != null)
{
logger.LogError(ex);
}
}
我想测试如果抛出错误,它会调用 LogError() 方法,该方法又会调用另一个对象。
我已经使用模拟记录器来解决这个问题,并捕获第一个抛出的异常,然后断言调用了 LogError 方法。但是,这感觉不需要捕获异常?我记得读过一些东西,在测试中尝试捕获是不好的?有没有其他方法来执行这个测试或者我应该重构逻辑?任何想法都会很棒!
[Test]
public void CreateTypedObjectInstance_GivenTypeWithoutPrivateContructor_LogErrorToLogger()
{
//Setup Method used
MockRepository mockery = new MockRepository();
ILogger mockedLogger = mockery.StrictMock<ILogger>();
genericObjectFactoryInstance.Logger = mockedLogger;
Expect.Call( delegate { mockedLogger.LogError(null); } ).IgnoreArguments();
mockery.ReplayAll();
// this will throw an error as String does not have a parameterless constructor
try
{
genericObjectFactoryInstance.CreateTypedObjectInstance<String>();
}
catch { /*ignore this error to test behaviour after*/ }
mockery.VerifyAll();
}
编辑
使用 Mark Rushakoff 答案,测试变得像魅力一样发挥作用。
[Test]
public void CreateTypedObjectInstance_GivenTypeWithoutPrivateContructor_LogErrorToLogger()
{
//Setup Method used
MockRepository mockery = new MockRepository();
ILogger mockedLogger = mockery.StrictMock<ILogger>();
genericObjectFactoryInstance.Logger = mockedLogger;
Expect.Call( delegate { mockedLogger.LogError(null); } ).IgnoreArguments();
mockery.ReplayAll();
Assert.Throws<MissingMethodException>(() => genericObjectFactoryInstance.CreateTypedObjectInstance<String>());
mockery.VerifyAll();
}
【问题讨论】:
-
通过在每行前面添加四个空格来格式化代码块。 StackOverflow 的 Markdown 语法将其显示为
<pre>标签。
标签: unit-testing exception-handling tdd nunit rhino-mocks