重构以编写"pretty" JUnit 测试



我想澄清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
}

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

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

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

你的类应该有WebService对象(我拒绝称它为"存根")作为字段。

class Someclass{
  @Resource
  private WebService ws;
  public void sendMessage(){
  ws.sendMsg();        
  }
}

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

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

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

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

相关内容

  • 没有找到相关文章

最新更新