Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Help with real world TDD using Java

Tags:

java

tdd

I'm looking for help on now to use TDD for a real world example. Most show are too simple and don't really show how test and re-factor more complicated classes. Here is an example of code that uses both a thread and a network socket. Could someone explain how to create a isolated Unit Test for such a class? Thanks.

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

}
like image 725
Jim Avatar asked Mar 15 '11 13:03

Jim


People also ask

Why TDD is not usually used?

This means the following problems in such a TDD approach: More test code than the implementation code. Not easy to design tests before the implementation is done. Implementation refactoring breaks existing tests.

Is TDD still relevant?

TDD is not dead in 2022. It will never be dead because there will always be projects where developers can use TDD effectively. Today and in the future, developers will want to make sure their code is not broken and works properly. By writing tests first, developers can see if they are on the right track or not.


2 Answers

Here's a couple of practical things to do to reduce your testing issues:

  1. Don't have your class inherit Thread. Make it a Runnable instead, because you can test a Runnable in isolation.
  2. Use dependency injection so that you can replace the Logger and the WebTestController with test versions (see "mocking").
  3. Remove anything from your code that doesn't do anything yet. Then test what you have. Add new stuff only when everything you have implemented is working and has valid tests to prove it

However I strongly recommend reading a good book about TDD and unit testing. The simple tutorials are just that - simple. They don't cover the complicated cases that you will run into in real life. It's perfectly possible to use TDD in real life, but it does take some knowledge - just like programming.

like image 126
DJClayworth Avatar answered Oct 16 '22 08:10

DJClayworth


Don't create such classes.

It would be better to break your logic into IO-related part and concurrency-related part. Then IO-related part can be tested, for example, with a mock socket implementation.

Testing concurrency-related logic would be more complex, though. It depends on behaviour you want to achieve.

like image 20
axtavt Avatar answered Oct 16 '22 06:10

axtavt