Java Reference
In-Depth Information
$ ant test
...
[junit] Running org.foo.mock.LogClientTests
[junit] Exception in thread "LogService Tester" java.lang.AssertionError:
[junit] Unexpected method call getBundle():
It appears that your client is using another method ( getBundle() ) on the Bundle-
Context to find the owning bundle when no LogService is available. If you look at the
rest of the client code under chapter07, you'll see that it uses this to get the bundle
identifier when logging directly to the console. You don't mind how many times your
client calls getBundle() , if at all, so let's use a wildcard expectation:
Bundle bundle = createNiceMock(Bundle.class);
expect(context.getServiceReference(LogService.class.getName()))
.andReturn(null);
expect(context.getBundle())
.andReturn(bundle).anyTimes();
You need to provide a new mock to represent your Bundle object. This time, instead
of simulating each method the client uses, you take a shortcut and use a nice mock on
the first line. Nice mocks automatically provide empty implementations and default
return values. You expect your log client to request this mock bundle from your mock
bundle context after you return the null service reference, but it may ask for it zero
or more times. One last thing you must remember to do is add your mock bundle to
the replay list. (If you happen to forget to replay a mock before it's used, you'll get an
IllegalStateException from EasyMock about missing behavior definitions.)
replay(context, serviceRef, logService, bundle);
With the new expectation in place and everything replayed, the test passes once more:
$ ant test
...
[junit] Running org.foo.mock.LogClientTests
[junit] <--> thread="LogService Tester", bundle=0 : LogService has gone
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 6.125 sec
Having sleep in your unit test is annoying, though. Every time you want to test addi-
tional log calls, you need to extend the sleep , which makes your tests run longer and
longer. You should try to replace it with some form of handshaking. But even with
handshaking, your log client will still pause for five seconds between each call. If only
you could replace the pause method while keeping the rest of the code intact.
7.2.4
Coping with multithreaded tests
You're currently testing a simple log client that spawns a separate thread to make log calls.
Knowing how to test multithreaded bundles is useful, because people often use threads
to limit the amount of work done in the activator's start method. As we mentioned at the
end of the last section, the main difficulty is synchronizing the test thread with the threads
being tested. Up to now you relied on sleep , but this is a fragile solution. Some form
Search WWH ::




Custom Search