Java – Mocking Camel endpoints with spring-configured camelContext

apache-camelintegration-testingjavajunitspring

I'm trying to figure out the "correct" way of mocking out an Endpoint in an integration test that uses spring test support.

The code is working, but I'm wondering if this is the correct way of doing it. I've looked at the camel-test Test Kit and it's adviceWith, but that is not useful when spring is responsible for loading the camelContex in the test, right?

This is what I have:

The service:

@Service
public class FtpOutboundFileStrategy implements OutboundFileExportStrategy {
    private final String FTP_PATTERN= "{0}://{1}@{2}";
    private final ProducerTemplate producerTemplate;

    @Autowired
    public FtpOutboundPriceFileStrategy(ProducerTemplate producerTemplate) {
        this.producerTemplate = producerTemplate;
    }

    @Override
    public void doExport(OutboundFile file, ExportProperties exportProperties) {
        this.producerTemplate.sendBodyAndHeader(createFtpUri(exportProperties),
                file.getFileContent(), Exchange.FILE_NAME, file.getFileName());
    }
}

The integration test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:testDB.xml", "classpath:applicationContext.xml"})
public class FtpOutboundFileStrategyIT {

    @EndpointInject(uri = "mock:ftp")
    protected MockEndpoint fakeEndpoint;

    @Autowired
    FtpOutboundFileStrategy ftpOutboundPriceFileStrategy;

    @Autowired
    protected CamelContext camelContext;

    @DirtiesContext
    @Test
    public void directsToFtpEndpoint() throws Exception {
        camelContext.addEndpoint("ftp://foo@localhost", fakeEndpoint);

        fakeEndpoint.expectedBodyReceived().equals("This is the file");
        ftpOutboundPriceFileStrategy.doExport(new OutboundFile("This is the file"),
                new ExportProperties("foo", "localhost"));
        fakeEndpoint.assertIsSatisfied();
    }
}

Now, this works, but I'm wondering if this is sort of a hack:

camelContext.addEndpoint("ftp://foo@localhost", fakeEndpoint);

I read somewhere that using @EndpointInject(uri = "mock:ftp") would create a mocked endpoint with higher present that the default FtpEndpoint, but if I leave this out the test fails because it's using the default.

Another strange thing is that if i use "ftp*" instead of "ftp://foo@localhost" in the mocks uri the test fails as well, which has led me to believe that this is not the correct way of doing it.

Any help is greatly appreciated!

Best Answer

I think David Valeri is working on improving camel-test-spring to be able to do more Camel stuff with the pure Spring Test Kit. There is a JIRA ticket, so keep an eye out for improvements in the future.

At first though you can use Spring property placeholders, to replace the endpoint uris, so when running the tests, you can substitute the actual ftp endpoints, with a mock endpoint etc.

See this FAQ about Spring XML limitations http://camel.apache.org/how-do-i-use-spring-property-placeholder-with-camel-xml.html

Chapter 6 in the Camel in Action book, also covers how to testing with Spring property placeholders, and have a test.properties and production.properties file that contains the actual endpoint uris.

Alternative in you test method, you can use the Camel advice-with API to alter the route and whatnot before running the test. See details here: http://camel.apache.org/advicewith.html

Related Topic