3

我想澄清 TDD 范围内的重构。

前:

class Somclass{
      public void sendMessage(){    
       WebServiceStub stub = new WebServiceStub();     
      ...
      stub.sendMsg();        
      }
    }

后:

class Somclass{
private WebServiceStub stub;

  public void sendMessage(){
    ...
  if(stub == null){
   stub = new WebServiceStub();
  }
  ...
  stub.sendMsg();        
  }
}

所以我想验证 sendMsg() 方法并用结果做一些断言。为了有可能模拟这个存根,我将这个存根局部变量移动到实例变量。这样我就可以将模拟存根设置为类并在测试类中进行验证和断言。例如:

@Test
public void testSMth(){
  wsProvider.setStub(stubMock);
  verify(stubMock).sendMsg();
  ...asserts
}

这种方法不是线程安全的,我应该做一些并发修改。这种修改可能会导致错误。所以在局部变量approce中有线程安全。

我也可以创建将返回 WebServiceStub 实例的工厂。但是这种方法会产生新的类,因为这种情况很常见。

有一个问题:如何测试这种情况,goot测试成本修改可能会导致错误吗?

4

3 回答 3

4

您的班级应该将WebService对象(我拒绝称其为“存根”)作为字段。

class Someclass{

  @Resource
  private WebService ws;

  public void sendMessage(){

  ws.sendMsg();        
  }
}

它应该注入您选择的 DI 框架。在您的测试中,您可以将其设置为模拟。正如您指出的那样,这不是线程安全的,因此不需要惰性吸气剂。

于 2012-04-27T09:53:32.487 回答
3

使用构造函数注入来避免未设置依赖项的可能性。这将使您可以轻松地在测试中使用模拟。

如果WebServiceStub该类实际上不是线程安全的(但如果WebServiceStub由 JAX-WS 生成,那么您应该知道 Metro/jax-ws 存根通常是线程安全的),那么是的,您将不得不使用工厂。这没什么大不了的,也不应该让你慢那么多。如果需要,您可以使用静态内部类。

于 2012-04-27T10:32:37.803 回答
0

它看起来几乎是正确的,但从不实例化存根,如果存根 == Null。相反,使用 ArgumentNullException。Null 永远不应该被接受为一个有效的论点(除非你有一个非常、非常、非常好的理由)。

于 2012-04-27T09:54:49.360 回答