我正在研究一个项目,我需要与吞噬异常的代码进行互操作。特别是,我正在编写NUnit单元测试。有些地方我想在代码中嵌入断言,作为委托传递,作为模拟特定行为的一部分。我遇到的问题是AssertionException被调用委托的代码吞没,这意味着测试通过,即使测试Assert失败。
有没有办法通知NUnit测试失败,无法通过捕获AssertionException来规避?我不能修改吞下异常的代码,因为我没有完全的所有权,而且它已经在半生产中使用了。我希望有一个干净的方法来实现这一目标。
我提出的最好的是这样的:
private static string _assertionFailure;
public static void AssertWrapper(Action action)
{
try
{
action();
}
catch (AssertionException ex)
{
_assertionFailure = ex.Message;
throw;
}
}
[Test]
[ExpectedException(typeof(AssertionException))]
public void TestDefeatSwallowing()
{
Action failure = () => AssertWrapper(() => Assert.Fail("This is a failure"));
EvilSwallowingMethod(failure);
if (_assertionFailure != null)
Assert.Fail(_assertionFailure);
}
private void EvilSwallowingMethod(Action action)
{
try
{
action();
}
catch
{
}
}
它有效,但它非常难看。我必须包装每个Assert调用,并且我必须在每次测试结束时检查是否吞下了一个断言。
答案 0 :(得分:2)
所以你正在做这样的事情? (这是使用Moq语法)
var dependency1 = new Mock<IDependency1>();
dependency1.Setup(d => d.CalledMethod([Args])
.Callback(TestOutArgsAndPossiblyThrow);
var objectUnderTest = new TestedObject(dependency1.Object);
objectUnderTest.MethodThatCallsIDependency1dotCalledMethod();
您的TestOutArgsAndPossiblyThrow
课程已封装AssertWrapper
吗?
除非那样离开,否则我说你做得恰到好处。您已执行重新进入测试的位置,您可以记录对依赖项的调用状态。无论是通过捕获异常并分析它们还是直接检查方法参数的值,您都必须完成这项工作。如果你在黑匣子内吞下异常,你将不得不在他们回到黑匣子之前对它们进行监控。
我仍然说你通过适当的日志记录和通知会更好(你不必通知最终用户)。要@ThenWill的观点 - 当IOException
或数据库不可用时,你做什么做?
讨论编辑
你的情景结构是这样的吗?
TEST -> TESTED CODE -> SWALLOWING CODE -> THROWING MOCK