2

Tried to test an OSGi service using JUnit and the tycho-surefire-plugin.

Configuration of the plugin

            <plugin>
                <groupId>org.eclipse.tycho</groupId>
                <artifactId>tycho-surefire-plugin</artifactId>
                <version>${tycho.version}</version>
                <configuration>
                    <showEclipseLog>true</showEclipseLog>
                    <dependencies>
                        <dependency>
                            <type>p2-installable-unit</type>
                            <artifactId>org.eclipse.equinox.ds</artifactId>
                        </dependency>
                    </dependencies>
                </configuration>
            </plugin>

Testcase (logging statements etc. omitted). The test class is contained in it's own OSGi bundle, separated from the code under test.

@Component(name = "LdapConnectionConfigurationServiceTest", immediate = true)
public class LdapConnectionConfigurationServiceTest {

    private LdapConnectionConfiguration testObject;


    @Reference
    public void bindTestObject(final LdapConnectionConfiguration testObject) {
        this.testObject = testObject;
    }

    public void unbindTestObject(final LdapConnectionConfiguration testObject) {
        this.testObject = null;
    }

    @Test
    public void testLdapPort() {
        assertEquals(10389, testObject.getLdapPort());
    }

}

Tycho starts an OSGi container, the test bundle, starts the LdapConnectionConfigurationServiceTest service and properly injects the testObject.

Subsequently JUnit runs this test case, but creates another instance of this class. Which doesn't get the testObject injected, so I'm getting NullPointerExceptions.

Don't know what I'm missing... What I want is running the test case against an injected service provided by the OSGi framework.

leftbit
  • 848
  • 1
  • 7
  • 18
  • When Tycho “starts the `LdapConnectionConfigurationServiceTest` service,” this is DS runtime creating your registered service. The JUnit test runner, however, doesn’t know about declarative services at all. In particular, it manages its own objects: It simply uses the default constructor of all present `*Test` classes to create a new object per `@Test`. I hope this explains what is going on. – Andreas Sewe Jul 13 '17 at 12:02
  • @AndreasSewe Yes, this is the case. Since JUnit runs under Tycho control I assumed Tycho would be clever enough to orchestrate the test accordingly. The whole point (my assumption) of using tycho-surefire-plugin over maven-surefire-plugin is the supposed ability to inject tested services into JUnit test cases. – leftbit Jul 13 '17 at 12:17
  • 1
    FWIW, I don’t think its a good idea to “inject tested services into JUnit test cases“. Here’s why: It makes it very hard to mock dependencies of your `testObject`; you would need to make the mocks available as services as well, so they can be injected into your `LdapConnectionConfiguration` (at the same time ensuring that you don’t accidentally inject any non-mocked dependencies). Also, your service descriptor file now becomes an integral but *non-local* part of your test case. Hence, I’d rather simply call the constructor directly and have all the set up local to my `*Test` class. – Andreas Sewe Jul 14 '17 at 13:43

0 Answers0