Java 如何在jUnit测试中强制方法抛出异常?

Java 如何在jUnit测试中强制方法抛出异常?,java,jakarta-ee,testing,junit,mockito,Java,Jakarta Ee,Testing,Junit,Mockito,实际上,这是为了代码覆盖率,我很难覆盖catch语句。 有什么想法吗 例如: 我想让我的selectSomethingBySomething()方法(从db中选择)抛出一个SQLException,这对测试方法来说非常困难,而且实际上不涉及实际的源代码。还有一个约束,我只能控制WHERE子句的参数。您需要首先模拟包含selectSomethingBySomething()的类,然后记录此行为。你会说: SomeDao someDaoMock = mock(SomeDao.class); wil

实际上,这是为了代码覆盖率,我很难覆盖
catch
语句。 有什么想法吗

例如:


我想让我的
selectSomethingBySomething()
方法(从db中选择)抛出一个
SQLException
,这对测试方法来说非常困难,而且实际上不涉及实际的源代码。还有一个约束,我只能控制
WHERE
子句的参数。

您需要首先模拟包含
selectSomethingBySomething()
的类,然后记录此行为。你会说:

SomeDao someDaoMock = mock(SomeDao.class);

willThrow(new SQLException())).given(someDaoMock).selectSomethingBySomething();

然后将
someDaoMock
注入测试中的类,当它调用
someDaoMock时。选择somethingbysomething()
它将抛出以前选择的异常。

有很多方法可以做到这一点,但我的建议是不要以100%的代码覆盖率为目标。这根本不值得。你让自己的生活变得困难,而收益微乎其微


然而,如果您真的想测试它,最好的方法可能是修改代码,使其更易于测试。让您的数据访问类实现一个接口,然后使用模拟框架(如JMock)模拟它并抛出SQLException。(您可以模拟具体的类,但这是不赞成的。)

使用EasyMock,您可以模拟一个类以及该特定类的方法调用

例如:

如果DoSomethingDAO是类名

像DoSomethingDAO mockDAO一样模拟类

EasyMock.createMock(DoSomethingDAO.class);
现在,您必须模拟从这个mockDAO发出的所有调用

如果该方法返回一个值,我们需要模拟调用,如下所示

EasyMock.expect(mockDAO.selectSomethingBySomething()).andReturn(EasyMock.anyObject());
如果该方法引发异常,下面是方法调用

EasyMock.expect(mockDAO.selectSomethingBySomething()).andThrow(new (typeofExecption));
对于void方法

mockDAO.selectSomethingBySomething();
EasyMock.expectLastCall().atleastOnce();

实际上,您不需要额外的框架来完成这项任务。 以下是如何:

    Exception hasToBeThrown = null;
    try {
                 methodThatShouldThrow();
    } catch (Exception e) {
        assertTrue(e.getMessage().startsWith("if you want to...")); // JUnit will miss this, if not thrown, so we need more
        hasToBeThrown = e;
    }
    assertNotNull(hasToBeThrown); // but this will do

您需要一个类似Mockito的模拟框架。在这里查看易于阅读的refcard:您应该模拟数据库连接对象,而不是实际向数据库发送SQL。您正在测试代码,而不是数据库。如果你不知道嘲弄,快速的谷歌搜索应该能找到很多好的介绍。