Reputation: 1648
I need to write Unit tests for production routes in Grails which use Services referenced by Camel bean component. My requirement is neither to change nor to copy existing routes in test.
Problem is to somehow mock Service bean and add it to Camel registry.
I was able to do this using 'bind' method on 'context.registry.registry' object. Is there any functionality to do that in more safe way? Camel version is 2.10, Grails 2.1
Route is:
from('direct:validate').to('bean:camelService?method=echo')
CamelService is just simple class:
package com
class CamelService {
def echo(text) {
println "text=$text"
text
}
}
Test is following (route copied only to make question simpler):
package com
import grails.test.mixin.*
import org.apache.camel.builder.RouteBuilder
import org.apache.camel.test.junit4.CamelTestSupport
@TestFor(CamelService)
class RouteTests extends CamelTestSupport {
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from('direct:validate').to('bean:camelService?method=echo')
}
};
}
void testMockBean() throws Exception {
context.registry.registry.bind 'camelService', service
def result = template.requestBody('direct:validate', 'message')
assert result != null
assert result == 'message'
}
}
Upvotes: 2
Views: 614
Reputation: 55555
Camel allows you to plugin any custom registry you want, and out of the box it uses a Jndi based registry, which is why you can bind a service to it with the code example. An alternative is to use a SimpleRegistry which is just a Map, so you can put a service into the registry using the put method from the Map. You would then need to override createCamelContext method from the CamelTestSupport class and pass in the SimpleRegistry to the constructor of DefaultCamelContext.
Anyway your code is safe as long you use the non-Spring CamelTestSupport class, as its using the JNDI based registrry out of the box. If you use CamelSpringTestSupport, then its a spring based registry, and you would need to use the spring app context to add your bean to it.
Upvotes: 1
Reputation: 18422
You can inject your components using CamelSpringtestSupport rather than CamelTestSupport as your base class.
Reading the documentation on Spring Test will help you for sure, and you might find interesting to use mock in your tests.
Anyway, you can build a custom context for your test, containing your bean's declaration and load it in the test.
public class RouteTests extends CamelSpringTestSupport {
@Override
protected AbstractApplicationContext createApplicationContext() {
return new ClassPathXmlApplicationContext("route-test-context.xml");
}
@Test
public void testMockBean(){
//...
}
}
route-test-context.xml
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://camel.apache.org/schema/cxf" xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="service" ref="com.CamelService"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<package>com</package>
</camelContext>
</beans>
Upvotes: 0