0

I have the following problem in my unit test. The class with tests:

class TestClass {
    boolean stopTest = false;

    @Test
    public void test() {
        // do something
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            public void run() {
                stopTest = true;
            }
        }, 1200);
        while(!stopTest) {
        }
        timer.cancel();
        // do assert
    }
}

This test works right only in debug with breakpoint on while operator, but if I run test not in debug or without breakpoint, he works infinitely. I tried to change stopTest to class with boolean field, also a tried to work through get and set methods in this class. What I do wrong?

Mirimon
  • 102
  • 5

3 Answers3

0

You need to use the volatile modifier due to concurrency, otherwise stopTest cannot be reliably updated and read. For more information, see JLS §8.3.1.4 - volatile Fields.

volatile boolean stopTest = false;
mrkhrts
  • 829
  • 7
  • 17
0

You should declare stopTest to be volatile.

See also:

Community
  • 1
  • 1
JRL
  • 76,767
  • 18
  • 98
  • 146
0

@JRL and @mrkhrts are right. But I would like to suggest something else.

You really do not need timer here. You just want to run some code in separat thread and make your main thread to wait until this asynchronous task is done. Do it using simple thread and join() method:

@Test
public void test() {
    // do something
    Thread t = new Thread() {
        public void run() {
            try {Thread.sleep(1200)} catch(InterruptedException e) {}
            // do what you want here
        }
    }
    t.start();

    t.join(); // this line will be bloked until the async task is done.
}
AlexR
  • 114,158
  • 16
  • 130
  • 208
  • The timer is more right for me, because also I want to check my object on timer's ticks. I didn't write it because I tried to change this test a lot. Thanks! – Mirimon Sep 27 '11 at 19:54