5

我有以下课程:

public class Foo {

  public Foo() {
     initField1();
     initField2();
     initField3();
  }

}

我需要改变行为(模拟)initField1()initField3()让他们什么都不做或他们实际做的其他事情。我有兴趣执行 initField2() 的实际代码。

我想编写以下测试:

Foo foo = new Foo();
assertTrue(foo.myGet());

myGet()返回由 Foo 计算的属性initField2()

这些initField()方法当然是私有的。

我怎么能做这样的事情?

感谢您的帮助和最诚挚的问候。

4

2 回答 2

5

考虑到遗留代码中可能发生任何事情:) 您可以使用http://code.google.com/p/powermock/wiki/SuppressUnwantedBehaviorPowerMock中描述的方法来抑制方法

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();
    }
}

不过,在获得足够的测试覆盖率后,您应该重新考虑该类。

于 2013-05-07T07:58:41.230 回答
-1

我认为你想做的事情有问题。

据我了解,Mockito 或 PowerMock 等模拟框架旨在模拟被测对象与其依赖项之间的交互。

据我了解您的问题,您想模拟部分对象行为,并测试其余部分。

在您的情况下,您想要测试永远不会发生的事情,因为initField2()如果没有调用initField1()initField3()

如果您不想调用的原因initField1()initField3因为这些方法与其他对象、文件系统或数据库交互,那么您应该通过构造函数参数或带注释的 setter 注入依赖项,并为您的测试注入模拟。要实例化您的对象并正确设置其依赖关系,请使用工厂模式、构建器模式,或者甚至更好,使用依赖注入框架,例如来自 Spring 或 Google Guice 的框架。

如果您不想调用的原因initField1()initField3因为它们处理对象中的不同业务逻辑,那么这闻起来(如在http://martinfowler.com/books/refactoring.html中)就像您正在打破单责任原则,你应该重构。

于 2013-05-06T19:29:11.717 回答