【发布时间】:2017-08-08 09:59:37
【问题描述】:
我正在尝试为看起来像这样的遗留代码编写测试:
public class TestedClass {
private A a = StaticFactory.createA();
private B b = StaticFactory.createB();
// No default constructor
// code using A and B classes
}
就我对 Mockito 的理解而言,我知道我不能模拟静态方法,但是我知道我可以使用一个小技巧并将这个对象的创建外部化为这样的封装私有方法:
public class TestedClass {
private A a;
private B b;
TestedClass() {
a = createA();
b = createB();
}
A createA() {
return StaticFactory.createA();
}
B createB() {
return StaticFactory.createB();
}
// code using A and B classes
}
但是使用这个结构我无法创建TestedClass 的间谍,它必须已经是一个间谍才能使用doReturn(..) 结构所以这样的测试不会起作用:
public class TestedClassTest {
TestedClass testedClass;
A mockA;
B mockB;
@Before
public void setUp() {
mockA = mock(A.class);
mockB = mock(B.class);
testedClass = Mockito.spy(new TestedClass());
doReturn(mockA).when(testedClass).createA();
doReturn(mockB).when(testedClass).createB();
}
}
有没有其他方法可以改变 createA 和 createB 方法的行为,这些方法在构造函数中被触发以确保我有模拟实例?
在这种情况下,StaticFactory.createA() 运行并抛出异常(正在测试中),无法完成测试的初始化。
Running pl.tbawor.TestedClassTest
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.168 sec <<< FAILURE!
shouldTestSomething(pl.tbawor.TestedClassTest) Time elapsed: 0.114 sec <<< ERROR!
java.lang.NullPointerException
at pl.tbawor.StaticFactory.createA(TestedClass.java:32)
at pl.tbawor.TestedClass.createA(TestedClass.java:14)
at pl.tbawor.TestedClass.<init>(TestedClass.java:9)
at pl.tbawor.TestedClassTest.setUp(TestedClassTest.java:26)
我的目标是避免运行创建 A 和 B 对象的原始方法,以防止抛出异常。
由于这是遗留项目,我无法添加任何其他库 (PowerMock)。
我会补充一点,TestingClass 修改应该尽可能少。
【问题讨论】:
-
使用PowerMock来做这个,它可以模拟静态方法,例如:stackoverflow.com/questions/10583202/…
-
谢谢,我也考虑过,但是这个项目里面不允许使用PowerMock..
标签: java unit-testing junit mockito