Unit testing 围绕异常的单元测试区域的正确方法是什么

Unit testing 围绕异常的单元测试区域的正确方法是什么,unit-testing,exception,Unit Testing,Exception,从单元测试的代码覆盖率来看,我们的代码覆盖率相当高。但是最后的几%是很棘手的,因为他们中的很多人都在捕捉数据库异常之类的事情——这在正常情况下是不会发生的。例如,代码防止字段太长等等,因此唯一可能的数据库异常是数据库被分解/破坏,或者模式在我们脚下被更改 那么,模拟对象以便抛出异常的唯一方法是什么呢?这似乎有点毫无意义。也许最好接受没有100%的代码覆盖率 谢谢, Dan当指定100%覆盖率目标时,一种常见的做法是通过测试覆盖尽可能多的代码,并通过代码评审覆盖剩余的几个百分比。通常在遇到低级异常

从单元测试的代码覆盖率来看,我们的代码覆盖率相当高。但是最后的几%是很棘手的,因为他们中的很多人都在捕捉数据库异常之类的事情——这在正常情况下是不会发生的。例如,代码防止字段太长等等,因此唯一可能的数据库异常是数据库被分解/破坏,或者模式在我们脚下被更改

那么,模拟对象以便抛出异常的唯一方法是什么呢?这似乎有点毫无意义。也许最好接受没有100%的代码覆盖率

谢谢,
Dan

当指定100%覆盖率目标时,一种常见的做法是通过测试覆盖尽可能多的代码,并通过代码评审覆盖剩余的几个百分比。

通常在遇到低级异常时,如Java中的IOException或SQLException,我会将它们包装到扩展运行时异常的异常中。我觉得测试这个行为是非常重要的,因为否则会有非常严重的意外吞咽异常的可能性

因此,如果您在抛出低级异常时确实执行了某些操作,我建议您测试它们

编辑:添加了示例

public void store(User user) {
    try {
        userDao.store(user);
    } catch (IOException e) {
        // Logging, perhaps some logic.
        throw new ServiceException(e);
    }
}

@Test(expected = ServiceException.class)
public void Store_Fail() {
    UserDao userDaoMock = createMock(UserDao.class);
    User user = // Create test user.
    userDaoMock.store(user);
    replay(userDaoMock);
    userService.store(user);
    verify(userDaoMock);
}
这里没有太多要测试的内容,但是如果逻辑要求抛出ServiceException,为什么不测试它呢?

那么,模拟对象以便抛出异常的唯一方法是什么? 我相信这是最简单的方法,但是你也可以做一个存根(也就是扩展真实对象的对象,强迫behvior每次抛出一个异常)。或者你可以使用AOP,但我认为使用像Or这样的库将是最简单的方法

这似乎有点毫无意义。也许最好接受没有100%的代码覆盖率? 每当我谈到这个话题时,我都喜欢改变人们的思维方式,不再担心某个百分比的覆盖率,而是将这个百分比作为一种工具,让你成为一名更好的开发人员。换句话说,100%覆盖率或50%覆盖率并不一定意味着您的代码编写得很好,甚至可以正常工作,而是在开发代码时使用代码覆盖率作为关键指标,以判断您是否在编写测试等方面有所懈怠。。。这是个好主意

我个人对您的问题的看法是,如果应用程序所做的是逻辑性的,那么它就值得测试。因此,如果您正在从该方法捕获和异常并重新调整false,则应该对此进行测试。如果您正在捕获异常并将其包装到另一个异常中,您应该对此进行测试。如果捕获异常而什么也不做,那么这应该是一种需要修复的代码味道,因为这可能会导致各种不可管理的副作用


至于100%是否不愤怒,我会说是的,这不值得。你应该为自己找到一个好的舒适度(也许80%,也许90%),并坚持下去。但我不会基于测试类型(如测试异常逻辑),它应该基于总覆盖率,并被视为在提交代码时没有编写测试的指标。

最后几个百分点通常不值得这么麻烦(当然,除非他们实现的功能是核心需求,那么你从错误的百分比开始;-)。异常处理代码通常充满bug-绝对值得测试。我必须同意Peli,我们正在做100%的测试,我们发现了很多可能的错误。你不应该一个代码一个代码地检查其余的代码吗?当然可以。但这篇具体的评论旨在证明为什么代码部分没有经过测试,以及为什么不测试它不会有什么害处。但是,是否可以将代码标记为“不包含”?目前,我们没有明确的方法从覆盖报告中确定哪些代码已经“代码审查”并被认为是可以的,哪些还没有?因此,我想获得一种伪100%覆盖率,其中所有代码都经过测试或审查。(我们使用的工具是EclEmma)通常您只需在行上添加一条注释,表明该行已被审阅。好的代码覆盖率工具应该提供一种方法来过滤掉带有适当格式注释的行,这些注释表明该行不需要覆盖。我不知道EclEmma是否提供了这种能力。那你怎么测试你的呢?你是在嘲弄这个错误,还是找到了一种真正触发它的方法?@Codek我赞同嘲弄。在那个特定的测试用例中,我将一个模拟对象注入到测试类中,并强制它在测试调用中抛出一个异常。我不会试图导致任何类型的文件或数据库错误,因为这非常耗时,有时甚至不清楚该方法为什么会抛出选中的异常。