相应的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;
}
}
}
在正常运行时,debugging为false,SystemTimeSynchronizer调用的是NtpClockWrapper实例。在单元测试时,可以在测试代码里将debugging设为true,这样SystemTimeSynchronizer实际调用的是SystemClock实例。
/**shannon.demo.unittest is the unit test codes
* package for the demonstration.
*/
package shannon.demo.unittest;
import shannon.demo.SystemTimeSynchronizer;
import shannon.demo.UnitTestFirewall;
import junit.framework.TestCase;
/**<code>SystemTimeSynchronizerTest</code> is the
* unit test class for SystemTimeSynchronizer
* @author Shannon Qian
*/
public class SystemTimeSynchronizerTest extends TestCase {
protected void setUp() throws Exception {
super.setUp();
UnitTestFirewall.setDebugging(true);
}
protected void tearDown() throws Exception {
super.tearDown();
}
public void testSyncTime() {
int result = new SystemTimeSynchronizer().syncTime();
assertTrue(result==0||result==1||result==-1);
}
}
另一方面,其实我们也看到了,如果NtpClock对象后面连着真正的NTP服务器,那么它永远只能返回正确的时间,而SystemTimeSynchronizer#syncTime()实际上提供了系统时间快于、慢于和恰好等于标准时间三种情况的处理逻辑。如果要测全三种场景,修改NTP服务器会是件麻烦的事情。或者为此等很长时间,还要看运气。所以目前为止,我们只能在SystemTimeSynchronizerTest#testSyncTime()里验证SystemTimeSynchronizer #syncTime()的返回值是{0, 1, -1}中的任何一个。
要方便的测试所有的处理逻辑分支,关键就是要能够随心所欲的控制Clock#getTime()的返回值。在此定义一个DebugClock替换原来的SystemClock类。
package shannon.demo;
/**
* <code>DebugClock</code> is a Clock for debugging.
* It accepts arbitrary value as candidate time for
* the next return of {@link #getTime()}
* @author Shannon Qian
*/
public class DebugClock implements Clock {
private long time=-1L;
/**Sets candidate time for debugging.
* @param t - the candidate time value in millisecond
* @see #getTime()
*/
public void setTime(long t) {
this.time=t;
}
/** Returns the time in millisecond.
* By default, it returns system time if the
* candidate time is not preset. else it will
* return the candidate time after reseting it.
* @return - time in millisecond
* @see #setTime(long)
*/
public long getTime() {
if(time<0L)
return System.currentTimeMillis();
long t=this.time;
this.time=-1L;
return t;
}
}
(未完待续)