技术开发 频道

谈谈单元测试中的测试桩实践

  在不配置NTP 服务器的情况下,单元测试肯定会因为异常抛出而中断。为了避免麻烦,

  我们首先想到的是如果不调用NtpClock 就好了。但如果不调用,就无法获取标准时间。这

  样我们只能另外造一个类,在单元测试时替代NtpClock,能够方便的提供标准时间。新的

  问题是SystemTimeSynchronizer 需要知道在不同时机调用不同的对象-在单元测试时,调用

  我们自定义的类,而在正常运行时仍然调用NtpClock.

  首先定义一个Clock 接口。并为Clock 实现两个具体类,一个是NtpClockWrapper,顾

  名思义其实就是实现了Clock 的NtpClock,另一个是SystemClock,它就提供系统当前时间

  作为标准时间。

  package shannon.demo;

  /**

  * Clock is an interface for all the clock to provide

  time.

  * @author Shannon Qian

  */

  public interface Clock {

  /**Returns the time in millusecond.

  * @return - the time in millusecond

  */

  public long getTime();

  }

  同时,我们定义一个UnitTestFirewall 类,维护一个debugging 标记。并提供一个getClock()

  类工厂方法,返回Clock 对象。

  package shannon.demo;

  import thirdparty.any.NtpClock;

  /**

  * UnitTestFirewall is the facility to

  * ease unit test

  * @author Shannon Qian

  */

  public final class UnitTestFirewall {

  private static boolean debugging=false;

  /**Returns true if it's in debugging mode, else false.

  * @return the debugging

  */

  public static boolean isDebugging() {

  return debugging;

  }

  /**Sets Debugging flag as true if it's time to unit test.

  * @param on - the debugging to set, true for on and false

  * for off

  */

  public static void setDebugging(boolean on) {

  UnitTestFirewall.debugging = on;

  }

  private final static NtpClock _ntpClock=new NtpClock();

  private static class NtpClockWrapper implements Clock {

  public long getTime() {

  return _ntpClock.getTime();

  }

  }

  private static class SystemClock implements Clock {

  public long getTime() {

  return System.currentTimeMillis();

  }

  }

  private static SystemClock sysClock = null;

  private static NtpClockWrapper ntpClock = null;

  /**Returns the Clock instance for SystemTimeSynchronizer's invocation.

  *

  * @return - Clock instance

  */

  public static Clock getClock() {

  if(debugging) {

  if(sysClock == null)

  sysClock = new SystemClock();

  return sysClock;

  } else {

  if(ntpClock == null)

  ntpClock = new NtpClockWrapper();

  return ntpClock;

  }

  }

  }

  相应的SystemTimeSynchronizer#syncTime()也做了修改,不再直接调用NtpClock。

  package shannon.demo;

  import thirdparty.any.NtpClock;

  public class SystemTimeSynchronizer {

  public int syncTime() {

  //long currentTime = new NtpClock().getTime();

  long currentTime = UnitTestFirewall.getClock().getTime();

  long interval = System.currentTimeMillis()-currentTime;

  if(interval == 0) {

  return 0;

  } else if(interval > 0) {

  return 1;

  } else {

  return -1;

  }

  }

  }

0
相关文章