Java Reference
In-Depth Information
You begin by expecting another log call, so remember to bump the latch count up to
three calls. The LogService is still available at this point, so you return the mock refer-
ence. The client is expected to dereference this by calling getService() , and at this
point you pretend the LogService has vanished and return null . You follow this by
expecting another wildcard call to get the bundle, just as you did in section 7.2.3,
because the log client may need it to do some alternative logging to the console.
Your test is now complete. You may want to compare it with the class in the solution
subdirectory. It covers normal and missing service conditions and the edge case where
the service is there to begin with but quickly disappears. Running it should expose the
problem that you know is there but couldn't re-create reliably on a real framework:
$ ant test
...
[junit] Running org.foo.mock.LogClientTests
[junit] <--> thread="LogService Tester", bundle=0 : LogService has gone
[junit] Exception in thread "LogService Tester"
java.lang.NullPointerException
[junit] at org.foo.log.Activator$LogServiceTest.run(Activator.java:66)
[junit] at java.lang.Thread.run(Thread.java:619)
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 5.205 sec
At this point, adventurous readers may want to copy the working service-lookup exam-
ple from chapter 4 (chapter04/dynamics/correct_lookup) and try testing it. One tip:
you'll need to extend the test to expect calls to ungetService() , because the working
example attempts to release the service reference after each successful call to get-
Service() . Whether you mandate calls to ungetService() or make them optional by
appending times(0, 1) to the expectation is completely up to you.
In this section, you learned how to mock out the OSG i API and script different sce-
narios when testing bundle-specific code that uses OSG i. Mocking helps you test situa-
tions that are next to impossible to recreate in a real container. It also provides a
counterpoint to the first section where you were running existing tests inside a real
container on code that often had no dependency on OSG i at all. The last section will
attempt to harmonize both approaches, by explaining how to script modular tests and
run them on a variety of frameworks.
7.3
Advanced OSGi testing
In the previous section, you successfully mocked out the OSG i API and ran your tests
without requiring a framework. Of course, the less you depend directly on an API , the
easier it is to mock. It's even easier if you use one of the component models from chap-
ters 11 and 12, because your dependencies will be indirectly injected by the component
framework. Such components rarely need to use the OSG i API themselves, so testing
becomes a matter of reconfiguring bindings to inject mocked-out dependencies in
place of the original instances. But as we discussed in section 7.1.1, eventually you'll
want to run tests on a real OSG i framework. These container tests typically don't
increase your code coverage—any unit and mocked-out tests should have already tested
the critical paths. Instead, these tests verify that your code conforms to the container:
Search WWH ::




Custom Search