【发布时间】:2014-03-29 10:50:56
【问题描述】:
这是我的情况,我有 2 个非常简单的类:
public class B {
public void doSomething(){
System.out.println("doSomething B reached");
}
}
还有:
public class A {
public void doSomething(){
B b = new B();
b.doSomething();
System.out.println("doSomething A reached");
}
}
我想用 Mockito 测试 A 类的方法 doSomething。因此,我想模拟 B 类的一个实例,并在实例化 B 类时将其提供给 A。出于隔离原因,我根本不希望达到 b.doSomething()。
我知道我可以通过创建以下单元测试来实现此行为:
@RunWith(PowerMockRunner.class)
public class TestA {
@Test
@PrepareForTest(A.class)
public void testDoSomethingOfA() throws Exception{
A a = PowerMockito.spy(new A());
B b = PowerMockito.mock(B.class);
PowerMockito.whenNew(B.class).withNoArguments().thenReturn(b);
a.doSomething();
}
}
导致输出:
doSomething A reached
所以这项工作!但是,我现在的问题是我们使用 Jococo 插件进行测试覆盖。 Jococo 不涵盖使用 @PrepareForTest(A.class) 语句测试的代码。我的公司重视准确的代码测试覆盖率。
我的问题:是否有另一种方法可以让 A 实例化 B 而不必使用 @PrepareForTest 语句?
非常感谢!
【问题讨论】:
-
不是让
B成为A的构造函数参数吗?或者至少是提供B实例的工厂?还是使用依赖注入? -
这将是我最后的选择!但我真的不想在重构之前触及现有代码。在重构之前,我真的很想要可靠的单元测试。
-
我知道代码不漂亮,我同意工厂或依赖注入是更好的解决方案,但此时我无法触摸代码
-
使用
PowerMock是避免问题而不是解决问题(类似于@fge 建议的)。我支持重构它以获取构造函数参数或使用工厂创建B。另请查看我在此处提供的选项,用于在没有PowerMock的情况下模拟这样的事情:stackoverflow.com/questions/21879804/… 查看可测试类解决方案 -
感谢 Avi,我认为现在我确实需要更改一些代码。我可能会创建一个受保护的方法来返回 B 的一个新实例,并且我会在我的单元测试中覆盖它(无论这在实际代码中有多难看,但此时情况不会变得更糟反正)。如果你给出答案,我会投票给它:)
标签: java unit-testing testing mockito powermock