Testing Sling-based applicationsPage edited by Bertrand DelacretazChanges (11)
Full ContentAutomated testing of OSGi components and services can be challenging, as many of them depend on other services that must be present or simulated for testing. This page describes the various approaches that we use to test Sling itself, and introduces a number of tools that can help testing OSGi and HTTP-based applications. Unit testsWhen possible, unit tests are obviously the fastest executing ones, and it's easy to keep them close to the code that they're testing. We have quite a lot of those in Sling, the older use the JUnit3 TestCase base class, and later ones use JUnit4 annotations. Mixing both approaches is possible, there's no need to rewrite existing tests. Tests that use a JCR repositoryUtility classes from our commons/testing module make it easy to get a real JCR repository for testing. That's a bit slower than pure unit tests, of course, but this only adds 1-2 seconds to the execution of a test suite. The RepositoryProviderTest in that module uses this technique to get a JCR repository. Note that our utilities do not cleanup the repository between tests, so you must be careful about test isolation, for example by using unique paths for each test. Mock classes and servicesThe next step is to use mock classes services to simulate components that are needed for testing. This makes it possible to test OSGi service classes without an OSGi framework. We have a number of custom-written mock services in Sling, like MockNodeType for example. These handwritten mocks implement just what's needed for their tests, so they might not be reusable as is. In other cases we use jmock to help create mock objects without having to write much code - such mocking libraries take care of the plumbing and allow you to write just the bits of code that matter (often with funny syntaxes). The tests of the org.apache.sling.event bundle, for example, make extensive use of such mock services. The problem with mocks is that it can become hard to make sure you're actually testing something, and not just "mocking mocks". At a certain level of complexity, it becomes quicker and clearer to actually start an OSGi framework for automated tests. Injecting services in private fieldsTo inject (real or fake) services in others for testing, without having to create getters and setters just for this, we use a reflection-based trick, as in this example: setting a private field via reflection // set resource resolver factory // in a ServletResolver object which has a private resourceResolverFactory field ServletResolver servletResolver = .... Class<?> resolverClass = servletResolver.getClass().getSuperclass(); final java.lang.reflect.Field resolverField = resolverClass.getDeclaredField("resourceResolverFactory"); resolverField.setAccessible(true); resolverField.set(servletResolver, factory);
Change Notification Preferences
View Online
|
View Changes
|
Add Comment
|
- [CONF] Apache Sling Website > Testing Sling-based applicatio... confluence
- [CONF] Apache Sling Website > Testing Sling-based appli... confluence
- [CONF] Apache Sling Website > Testing Sling-based appli... confluence
- [CONF] Apache Sling Website > Testing Sling-based appli... confluence
- [CONF] Apache Sling Website > Testing Sling-based appli... confluence
