我想为以下类编写单元测试:
public class Target() {
private final Member member = new Member();
public Target() {
}
}
我想用模拟的Member实例初始化这个Target类,因为在测试期间实例化Member是不可行的。这在任何框架下都可能吗?
编辑:
我不想嘲笑Target类。我打算在初始化时模拟Member类。
Object method() {
member.differentMethod();
//Logic which I want to test
}
请建议如何模拟对Member类方法的调用。
要构建Prim的答案(投票支持),只需给自己两个构造函数。
public class Target() {
private final Member member;
public Target() {
this.member = new Member();
}
/** Testing constructor. Package-private visibility for tests in the same package. */
Target(Member member) {
this.member = member;
}
}
通过提供多个构造函数,您可以确保生产中的消费者根本不需要更改。这也是一个与"测试代码污染生产"不同的情况:您的一个用例(特别是测试)需要自定义Member实现,并且您为替换该成员提供了最封装的访问权限。
另请参阅:当我们无法将mock对象传递给类的实例时,如何使用Mockito
您可以将构造函数mocking与Powermock一起使用:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Target.class)
public class Test {
@Test
public void doSomething() throws Exception {
Member mockMember = mock(Member.class);
PowerMockito.whenNew(Member.class).thenReturn(mockMember);
Target thisTargetWillHaveYourMockAsField = new Target();
//Your test code
}
}
您应该将Target类使用的Member实例传递到Target类的构造函数中。
通过这样做,您可以在生产环境中使用Member类的实现,并在测试环境中使用另一个实现(可能为空)。
最佳的解决方案是使用依赖反转/注入原理