Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test a timer?

Tags:

java

junit

timer

I would like to write a test for a method, that calls observers in a specific intervall, so that they will execute a method. The timer-object runs in its own thread.

Method of timer to be tested
private long waitTime;

public Metronome(int bpm) {
    this.bpm = bpm;
    this.waitTime = calculateWaitTime();
    this.running = false;
}

public void run() {
    long startTime = 0, estimatedTime = 0, threadSleepTime = 0;

    running = true;

    while (running) {
        startTime = System.nanoTime();

        tick();// notify observers here

        estimatedTime = System.nanoTime() - startTime;
        threadSleepTime = waitTime -estimatedTime;
        threadSleepTime = threadSleepTime < 0 ? 0 : threadSleepTime;

        try {
            Thread.sleep(threadSleepTime / 1000000l);

        } catch (InterruptedException e) {
                // sth went wrong
        }
    }
}
Snippet from my testclass
private int ticks;
private long startTime;
private long stopTime;

@Test
public void tickTest(){
    metronome.setBpm(600);
    startTime = System.nanoTime();
    metronome.run();
    long duration = stopTime - startTime;
    long lowThreshold  =  800000000;
    long highThreshold =  900000000;
    System.out.println(duration);
    assertTrue(lowThreshold < duration); 
    assertTrue(duration <= highThreshold);      
}

@Override
public void update(Observable o, Object arg) {
    ticks ++;       
    if(ticks == 10){
        metronome.stop();
        stopTime = System.nanoTime();
    }
}

Right now, my testclass registers as an observer at the object in question, so that i can count the number of times tick() was executed. The test measures the time before and after the execution, but it feels awkward to me, to test the behaviour this way.

Any suggestions for improving the test?

like image 462
ccaspers Avatar asked Sep 24 '12 22:09

ccaspers


People also ask

What is a test timer?

A test timer is just that, a signal that the panel knows that 24 or 168 hours or one month has elapsed since the last initiated signal.


1 Answers

Sometimes the solution is to use something from a standard library that is sufficiently simple such that it does not need to be tested. I think SchedulerExecuterService will do the trick for replacing the home made Timer being tested here. Note that it is pretty rare to be bit by a bug in library code, but they do exist.

In general though, I think it is okay to create a helper class or use a mocking framework (Mockito) to do something simple like counting "ticks".

P.S. You can replace Thread.sleep(threadSleepTime / 1000000l) with TimeUnit.NANOSECONDS.sleep(threadSleepTime) ... which moves some logic from your code into the standard library.

like image 186
Tim Bender Avatar answered Sep 19 '22 00:09

Tim Bender