如何模拟我在测试中无法实例化的对象?

Sve*_*ven 9 java easymock mocking

我在我的测试中使用EasyMock来模拟对象.但是,我如何模拟在我的代码中的其他位置创建的对象?查看以下psudo代码.我想模拟WebService#getPersonById,我该怎么做?

public class Person {
  public Person find(int id) {
    WebService ws = new WebService();
    return ws.getPersonById(id);
  }
}

public class PersonTest {
  testFind() {
    // How do I mock WebService#getPersonById here?
  }
}
Run Code Online (Sandbox Code Playgroud)

hvg*_*des 9

如果您使用控制和依赖注入的反转来连接您的服务,模拟通常很有效.所以你的人应该是这样的

public class Person() {
  WebService ws = null;

  // or use setters instead of constructor injection
  Persion(WebService ws) {
     this.ws = ws;
  }
  public Person find(int id) {
    return ws.getPersonById(id);
  }
}
Run Code Online (Sandbox Code Playgroud)

希望很明显,通过这个更改,您现在可以为WebService创建一个模拟和模拟控件,并将其插入到您的测试中,因为当您创建要测试的Person时,您可以将模拟传递给构造函数(或setter)如果你去那条路)

在您的真实环境中,IoC容器将注入真正的Web服务.

现在,如果你不想处理所有这些IoC的东西,你需要做的就是将你的web服务与你的Person分开(应该调用PersonService或者其他东西,而不仅仅是Person,它表示实体).换句话说,编写代码的方式只能使用一种类型的WebService.你需要这样做,所以Person只需要某种类型的WebService,而不是你硬编码的特定类型.

最后,在编写的代码中,WebService是一个类,而不是一个接口.WebService应该是一个接口,您应该进行某种实现.EasyMock适用于界面; 它可能能够模拟具体的类(自从我实际使用它以来已经有一段时间了),但作为一个设计原则,你应该指定所需的接口,而不是具体的类.