使用Java帮助实际的TDD

时间:2011-03-15 13:23:27

标签: java tdd

我正在寻求帮助,以便将TDD用于真实世界的示例。大多数节目过于简单,并没有真正展示如何测试和重新考虑更复杂的类。以下是使用线程和网络套接字的代码示例。有人可以解释如何为这样的类创建一个独立的单元测试吗?感谢。

public class BaseHandler  extends Thread {
  protected Socket mClientSocket;
  protected BufferedReader is = null;
  protected BufferedWriter os = null;
  private Logger mLogger = Logger.getLogger(WebTestController.class.getName());
  protected WebTestController mWebTestController;

  /*********************************************************************
   * 
   * @param piPort - int port to listen on
   */
  public BaseHandler(){
  }


  /*********************************************************************** cleanup
   * Ensure sockets are closed as to not run into bind errors
   */
  protected void cleanup() {
    try {
      if (is != null)
        is.close();
      if (os != null)
        os.close();
      if (mClientSocket != null)
        mClientSocket.close();
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    mLogger.info("cleaning up a socket");
  }

  /***********************************************************************************
   * Sends a message to the current socket
   * @param pMessage
   */
  protected void writeToSocket(String pMessage){
      try {
          os = new BufferedWriter(
            new OutputStreamWriter(mClientSocket.getOutputStream()));

        }
        catch (IOException e) {
          e.printStackTrace();
          cleanup();
          return;
        }
        try {
            os.write(pMessage, 0, pMessage.length());
            os.flush();
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        cleanup();
  }

}

5 个答案:

答案 0 :(得分:5)

不要创建这样的类。

最好将您的逻辑分解为与IO相关的部分和与并发相关的部分。然后可以测试与IO相关的部分,例如,使用模拟套接字实现。

但是,测试与并发相关的逻辑会更复杂。这取决于你想要实现的行为。

答案 1 :(得分:5)

以下是一些减少测试问题的实际操作:

  1. 不要让你的类继承Thread。改为使其成为Runnable,因为您可以单独测试Runnable。
  2. 使用dependency injection以便您可以使用测试版本替换Logger和WebTestController(请参阅“模拟”)。
  3. 从您的代码中删除任何尚未执行任何操作的内容。然后测试你拥有的东西。只有当您实施的所有内容都正常工作并且具有有效的测试证明它时才添加新内容
  4. 但是我强烈建议您阅读一本关于TDD和单元测试的好书。简单的教程就是这么简单。它们不包括您将在现实生活中遇到的复杂案例。在现实生活中使用TDD是完全可能的,但它确实需要一些知识 - 就像编程一样。

答案 2 :(得分:1)

AFAIK你应该从测试驱动开发中的测试用例开始。我建议你从测试开始,这个类应该先通过并将其作为原型。

您必须创建一个类或子类,它将打开Socket到虚拟ServerSocket并向其发送消息。

答案 3 :(得分:1)

代码不“使用”一个线程,它只是一个派生自java.lang.Thread的类。在您测试课程而不是run()中的功能之后,没有什么能阻止您直接调用java.lang.Thread方法。

事实上,您希望测试cleanup()writeToSocket方法,因此无需调用run()方法。

只需创建BaseHandler的子类,使用一些模拟对象初始化该子类中的成员,然后就可以了。

但是,您可能需要进行其他更改才能使代码的其余部分更容易测试。我假设这个问题更多的是关于单元测试现有代码库而不是关于TDD。

答案 4 :(得分:1)

本课程不尊重SRP(Single Responsibility Priciple)。你的班级做了太多的逻辑。 相反,您应该将此类拆分为多个较小的类。然后,您通常会使用Spring或其他IoC框架注入这些类。

如果你要分开课程,你会发现它会更容易测试。您可以为这些组件提供模拟对象,并根据需要在每个测试用例中注入它们,因为它最适合您。