Reputation: 3091
I have multiple routes classes defined in my project under com.comp.myapp.routes. For testing these I am mocking the end route and checking/comparing delivery received.
Say for example I have below routes:
public class MyRoute1 extends RouteBuilder {
public void configure() throws Exception {
//Route_1 code
}
}
public class MyRoute2 extends RouteBuilder {
public void configure() throws Exception {
//Route_2 code
}
}
....
...//some route impl
..
public class MyRouteN extends RouteBuilder {
public void configure() throws Exception {
//Route_N code
}
}
Now for all these routes the test case that I wrote seems same. First mock it.
Mock for MyRoute1:
public class MyRoute1_Mock extends RouteBuilder {
public void configure() throws Exception {
from("direct:sampleInput")
.log("Received Message is ${body} and Headers are ${headers}")
.to("mock:output");
}
}
Test for MyRoute1:
public class MyRoute1_Test extends CamelTestSupport {
@Override
public RoutesBuilder createRouteBuilder() throws Exception {
return new MyRoute1_Mock();
}
@Test
public void sampleMockTest() throws InterruptedException {
String expected="Hello";
/**
* Producer Template.
*/
MockEndpoint mock = getMockEndpoint("mock:output");
mock.expectedBodiesReceived(expected);
String input="Hello";
template.sendBody("direct:sampleInput",input );
assertMockEndpointsSatisfied();
}
}
Now to make unit test for other classes just copy and paste the above code with different name say MyRoute2_Test , MyRoute3_Test , ...MyRouteN_Test.
So what did it actually tested? It's just written for the purpose of writing test case. It actually just checks/tests if mock library and camel-test library work or not Not our code works or not? How should it actually be done?
Upvotes: 5
Views: 11098
Reputation: 7005
You want to test your Camel routes but in the test you mock them away. So yes, you are testing your route mock instead of the real route.
To test your real routes:
from
endpointfrom
endpoint (not the entire route!) by replacing it with a direct
endpoint. This is quite easy with adviceWithto
endpoint receives the correct message by mocking these endpoints too. Again, use adviceWith for that. And Camel Mock of courseIf you are completely new to Camel route tests, get Camel in Action 2nd edition. It explains all mentioned testing aspects for Camel applications on 65 pages. And of course it also takes you on a complete ride through the Camel universe on much more pages.
By the way: if testing your routes is hard, they are too complex. Start to divide your routes so that they are easily testable.
Upvotes: 2
Reputation: 16
Explained in-line,Hope this helps you understand significance of Mock in Unit Test:
public void sampleMockTest() throws InterruptedException {
String expected="Hello";
MockEndpoint mock = getMockEndpoint("mock:output");//Mocking endpoint
mock.expectedBodiesReceived(expected); //Setting expected output to mocked endpoint
String input="Hello";
template.sendBody("direct:sampleInput",input );//triggering route execution by sending input to route
assertMockEndpointsSatisfied(); //Verifies if input is equal to output
}
If your endpoint is Rest service you can make use of "TestRestTemplate" instead of Mocking it and Test like below:
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class SampleCamelApplicationTest {
}
import org.springframework.boot.test.web.client.TestRestTemplate;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class SampleCamelApplicationTest {
@Autowired
private TestRestTemplate restTemplate;
}
@Test
public void sayHelloTest() {
// Call the REST API
ResponseEntity<String> response = restTemplate.getForEntity("/camel/hello", String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
String s = response.getBody();
assertThat(s.equals("Hello World"));
}
Upvotes: 0
Reputation: 1590
The route you show doesn't really do anything to the messages traversing it, so testing that the same text you sent in one end comes out the other is all there is to test.
For routes with more data transformation and processing, you could test the output data types, that processors were called when needed, you could mock in throwing of exceptions, etc. What you have above is a good start on that.
Upvotes: 0