Search code examples
mavenintegration-testingmaven-surefire-pluginmaven-failsafe-plugin

Surefire able to run test, failsafe not


I have some integration-tests that run perfectly using the surefire plugin with command:

mvn -Dtest=path.to.test.classIT surefire:test

When I run the same integrationtest with the failsafe plugin using

mvn verify

the test fails indicating it is missing a dependency (jackson lib, "No Message body writer found for response class ").

The needed dependency is added to the pom with scope test. What is the difference in how surefire and failsafe executes tests?

Some more context: My pom contains the following:

...
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.12.4</version>
    <configuration>
        <forkMode>never</forkMode>
        <threadCount>1</threadCount>
    </configuration>
</plugin>
...
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-core</artifactId>
        <version>1.9.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.openejb</groupId>
        <artifactId>openejb-cxf-rs</artifactId>
        <version>4.6.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.apache.openejb</groupId>
        <artifactId>openejb-mockito</artifactId>
        <version>4.6.0</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.jaxrs</groupId>
        <artifactId>jackson-jaxrs-json-provider</artifactId>
        <version>2.2.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>javax</groupId>
        <artifactId>javaee-web-api</artifactId>
        <scope>provided</scope>
    </dependency>

The test class uses applicationcomposer

@RunWith(ApplicationComposer.class)
public class PdaServiceIT {

    ....
    @Configuration
    public Properties config() throws Exception {

        Properties properties = new Properties();

        properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
        properties.setProperty(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE, "true");
        properties.setProperty("cxf.jaxrs.providers", "com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider");

        return properties;
    }
...

Solution

  • The problem might be caused because the class used as Json provider is not on the classpath. This can be solved by adding a module that contains the class to the integration test:

    ...
    @RunWith(ApplicationComposer.class)
    public class PdaServiceIT {
    
        ...
        @Configuration
        public Properties config() throws Exception {
    
            Properties properties = new Properties();
    
            properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
            properties.setProperty(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE, "true");
            properties.setProperty("cxf.jaxrs.providers", "com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider");
    
            return properties;
        }
    
        @Module
        public static Class<?>[] myJaxbProviders() {
            return new Class<?>[] { com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider.class };
        }
        ...
    }
    

    Then the required class will be available when using both maven-surefire and maven-failsafe plugins.

    A similar integration test setup is described here.