6

I want to test that some method would be recalled on failing. Calling executed in separate thread. So I write code like this

final Foo mock = createStrictMock(Foo.class);

mock.bar();
expectLastCall().andThrow(new RuntimeException("TEST EXCEPTION"));
mock.bar();
replay(mock);

doStuff();
sleepSomeTime(); //Pretty dirty. But I need to test it in multithreading.
verify(mock);

And test passed. But I did not implement recall yet.

To make test fail, I replaced

 mock.bar();
 expectLastCall().andThrow(new RuntimeException("TEST EXCEPTION"));

with

 mock.bar();
 expectLastCall().andAnswer(new IAnswer<Void>() {
        @Override
        public Void answer() throws Throwable {
            sleepSomeTime();
            throw new RuntimeException("TEST EXCEPTION");
        }
    });

But I don't like adding sleepSomeTime all around my tests. Beside that, I don't actually understand while it helps in this particular case. So,

Why adding delay helped?

What the right way to do such stuff?

Stan Kurilin
  • 15,614
  • 21
  • 81
  • 132

3 Answers3

7

My approach has been to use locks. There isn't quite enough info in your post to show something definitive, but it'd probably look something like this:

final Lock lock = new Lock();
lock.lock();
expectLastCall().andAnswer(new IAnswer<Void>() {
    @Override public Void answer() throws Throwable {
        lock.unlock();
        throw new RuntimeException("TEST EXCEPTION");
    }
});     
doStuff();
lock.lock();
verify(mock);

The gist here is the second lock() invocation is blocked until the unlock in your mock frees up the lock.

Chris Kessel
  • 5,583
  • 4
  • 36
  • 55
0

There is no easy way to perform unit test in a multi-thread context.

But I suggest you to read this answer to another similar question. The DRTestUtils provides a few convenient methods to hide the Thread.sleep behind a nicer waitForCondition method call.

Community
  • 1
  • 1
ben75
  • 29,217
  • 10
  • 88
  • 134
-1

Have you tried to implement using swing workers?

Also what you might want to try is if you are waiting then you might want to try and use notify or using a synchronized class.