我有以下课程:
public class Foo {
public Foo() {
initField1();
initField2();
initField3();
}
}
我需要更改行为(模拟)initField1()
和initField3()
,因为他们不做任何事情或他们实际做的其他事情。我有兴趣执行initField2()的实际代码。
我想写下面的测试:
Foo foo = new Foo();
assertTrue(foo.myGet());
myGet()
返回由initField2()
计算的Foo属性。
initField()
方法当然是私有的。
我怎么能这样做?
感谢您的帮助和最诚挚的问候。
答案 0 :(得分:5)
考虑遗留代码中可能发生的任何事情:)您可以使用PowerMock
来压制http://code.google.com/p/powermock/wiki/SuppressUnwantedBehavior
import static org.powermock.api.support.membermodification.MemberMatcher.methods;
import static org.powermock.api.support.membermodification.MemberModifier.suppress;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Foo.class)
public class FooTest {
@Test
public void testSuppressMethod() throws Exception {
suppress(methods(Foo.class, "initField1", "initField3"));
Foo foo = new Foo();
}
}
但是,在你获得足够的测试覆盖率之后,你应该重新考虑这个课程。
答案 1 :(得分:-1)
我认为你想做的事情有问题。
据我所知,Mockito或PowerMock等模拟框架旨在模拟被测对象与其依赖关系之间的交互。
正如我理解你的问题,你想要模仿部分对象行为,并测试其余部分。
在您的情况下,您希望测试一些永远不会发生的事情,因为如果不调用initField2()
和initField1()
initField3()
如果您不想调用initField1()
和initField3
的原因是因为这些方法与其他对象或文件系统或数据库交互,那么您应该通过构造函数参数注入依赖项或注释的setter,并为您的测试注入模拟。要通过正确设置依赖项来实例化对象,使用工厂模式,构建器模式,甚至更好,使用依赖注入框架,例如Spring或Google Guice中的依赖注入框架。
如果您想要调用initField1()
和initField3
的原因是因为它们处理对象中的不同业务逻辑,那么这就是闻起来(如http://martinfowler.com/books/refactoring.html中所述)像你一样违反单一责任原则,你应该重构。