我应该强制例外来测试它们吗?

时间:2009-09-26 18:16:42

标签: c# .net unit-testing exception logging

我在我的数据访问类中有这个方法,我有一个单元测试,以确保它正常工作,但我的测试不测试异常,所以我的问题是我应该创建一个新的测试来强制异常被提出或者我应该相信catch块在异常的情况下会正常工作吗?这是值得的吗?

这是一个例子:

public void UpdateProject(Project project)
    {
        using (var transaction = _session.BeginTransaction())
        {
            try
            {
                _session.Update(project);
                _session.Flush();
                transaction.Commit();
            }
            catch (HibernateException)
            {
                transaction.Rollback();
                throw;
            }
        }
    }

8 个答案:

答案 0 :(得分:11)

理想情况下,您应该尝试测试您可以使用的每一行代码......这将意味着强制发生异常以测试异常处理程序,并确保其正常工作。

在实践中,总会有一些代码行未被覆盖 - 但是,我会通过模拟强制执行异常,以便测试您认为至关重要的异常处理程序,尤其是或者可能在生产中发生的异常处理程序。 p>

答案 1 :(得分:9)

在Linux内核中,驱动程序中80%的错误都在错误处理代码中。

异常处理是许多错误的根源,您肯定应该测试所有异常路径。

当然你无法测试每一行代码。但统计数据显示,程序员对异常处理的关注较少,因此必须对其进行彻底的测试。

答案 2 :(得分:4)

以下是我对失败行为进行理想测试的规则:

  • 如果您使用的依赖项可能会引发异常,那么您应该包含单元测试,这些单元测试会让您的模拟器抛出异常。
  • 如果在某些情况下您的代码应该抛出异常,那么您应该包含设置此类条件的单元测试。

第一个可让您了解代码在外部故障下的行为,并且经常会重新考虑要做什么。在所有情况下,很高兴看到实际发生的事情。 第二个只是确保您保留您所承诺的内容,只要您的代码应检测到的错误并考虑异常。它与测试代码中的其他功能没有什么不同。

在考虑完成单元测试套件之前,应该先看看被测代码的代码覆盖率。对于非平凡的代码,我的代码分支几乎总是有一种方法,我的单元测试没有覆盖,或者更糟糕的是,我有不想要的行为。令人惊讶的是,解决方案是删除该代码而不是添加更多测试。只是在早些时候甩开它时留下了残留物。

我不一定说人们应该达到100%的覆盖率,但是应该进行代码覆盖率驱动的单元测试,因为它是一种更直观的方式来理解和暴露存在的代码行为。只需查看它就可以为您提供有关如何重构代码以实现Single Responsibility PrincipleSeparation of Concerns的新想法。

答案 3 :(得分:3)

你可以让你的会话模拟抛出异常,但几乎没有必要测试一个catch是否有效。

如果更新引发异常但是在直觉级别上编写测试来检查事务是否已回滚并没有错,我认为这样做太过分了。

也许更精心的案例是值得的。

另外请注意,你不会回滚任何类型的异常吗?

答案 4 :(得分:3)

我希望如果在Commit()之前调用Displose(),那么事务将是Rollback,因此你是否需要catch?

至于其他情况,如果你的捕获更多,那么只记录问题,我认为应该进行单元测试。 但是不要让事实上你不能做利润单元测试阻止你做一些单元测试。

答案 5 :(得分:1)

从异常名称(HibernateException)我认为这不是一个例外情况。所以它可能在正常操作期间发生。如果是这种情况,我会做一个导致异常的测试,以确保它得到妥善处理。

答案 6 :(得分:1)

我当然会测试捕获和处理的每个特定异常。至少你在处理代码中有一些执行路径,这应该会给你一些安慰,当你在运行时遇到这样的异常时,不会发生任何其他奇怪的事情。

请记住,您只需要测试您想要使用的代码。

答案 7 :(得分:1)

我当然希望你能单独测试transaction.Rollback()测试,这些测试会耗尽你能想到的所有可能情况。但是,如果测试是详尽无遗的,那么我可能不会费心提出异常,因为处理程序中没有别的东西。