实际上这是为了代码覆盖,我很难覆盖到catch
语句。有任何想法吗?
例如:
我希望我的selectSomethingBySomething()
方法(从 db 中选择)SQLException
在不实际接触实际源代码的情况下在测试方法上抛出一个非常困难的方法。还给出了我只能控制的是WHERE
子句的参数的约束。
实际上这是为了代码覆盖,我很难覆盖到catch
语句。有任何想法吗?
例如:
我希望我的selectSomethingBySomething()
方法(从 db 中选择)SQLException
在不实际接触实际源代码的情况下在测试方法上抛出一个非常困难的方法。还给出了我只能控制的是WHERE
子句的参数的约束。
您需要首先模拟包含的类selectSomethingBySomething()
,然后记录此行为。在模拟中,您会说:
SomeDao someDaoMock = mock(SomeDao.class);
willThrow(new SQLException())).given(someDaoMock).selectSomethingBySomething();
然后注入someDaoMock
您的测试类,当它调用时,someDaoMock.selectSomethingBySomething()
它会抛出先前选择的异常。
使用 EasyMock,您可以模拟一个类和该特定类的方法调用。
例如:
如果 DoSomethingDAO 是 ClassName,
像 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();
有很多方法可以做到这一点,但我的建议是不要以 100% 的代码覆盖率为目标。这根本不值得。你为了微不足道的好处让自己的生活变得困难。
但是,如果您真的想对其进行测试,最好的方法可能是更改您的代码以使其更具可测试性。让你的数据访问类实现一个接口,然后使用一个模拟框架(例如 JMock)来模拟它并抛出一个 SQLException。(你可以模拟具体的类,但这是不受欢迎的。)
你实际上不需要额外的框架来完成这个技巧。方法如下:
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