Testing Apache Camel 3.13.x in SpringBoot application in examples
Apache Camel is a framework for data transformation and delivery.
In a few words:
- Apache Camel gives you a DSL (Domain Specific Language) that helps you to describe how the data should be transformed.
- Apache Camel has over 330 different connectors, by means of which you could easily gather your data and deliver it wherever it needs.
- Apache Camel provides you a mechanism of thread manipulation under the hood to process any job in parallel.
Consider I have a folder. And text files are being collected in this folder by the other application.
My task is to check every file on bad words (e.g. duck) to replace it with a good one (e.g. ostrich).
You could think about fetching each file to process it line-by-line superseding each bother word with permitted one.
You are correct. I’ve implemented it for you in Camel. Take a look.
How to test this code? - you may ask. And the answer is — let’s write a test.
After reading official documentation about how to test Apache Camel applications I need to add all needed dependencies (consider of using maven or gradle).
N.B.! When writing a test covering Apache Camel Route it should not test the side of work that Apache Camel does. It should not test how Camel connects to AWS or sends email — all such stuff is tested already in Apache Camel sources. You should implement a test covering only functionalities instead.
According to this rule I should not listen to new files in a folder, should not write the result into another folder. All I should do — is to mock my IN and OUT folders and test if my data transformation is correct.
In order to mock my from- and to-endpoints I’m going to remove folders names explicitly specified into endpoints definition and put them in another Spring Bean — property provider. It will be straightforward to substitute folders with mocks in my test.
I am to construct an interface providing input and output endpoints and the class implementing it.
And another property provider for test with mocked endpoints.
So my test is below.
Notice the following:
- Test is annotated with
classesproperty specified with Application class
- In test method mocked endpoint is adjusted with several expectations
- After a message is sent into from-endpoint the mocked endpoint checks all caught messages on expectations to be satisfied
So when you run this application with options
creating two folders
/tmp/out beforehand, every file placed into
/tmp/in is to be processed and every ‘duck’ becomes ‘ostrich’ now. Let’s see it.
$ echo "123 duck
789 duck tales" > /tmp/in/test
$ cat /tmp/out/test
689 ostrich tales
Now consider I’m interested in supervision each file with external Supervisor over HTTP. The Camel Route becomes the following.
My test becomes red as expected.
How do I deal with it now? What is if external service for supervising is not available from CI/CD where tests to be run? What is if this external service is not available even from my laptop? The answer is — to disable external service call in test without changing route definition.
I am to move external endpoint definition into Property Provider to segregate production and test code.
Ok, how about my test?
Apache Camel Test KIT provides a tool called Advice which helps you to mock dealing with external services. You can “advice” Camel to (e.g.) set a concrete value into body instead of calling external service. The test becomes as following.
But the only thing you should remember is how to enable this Advice mechanism. It is enabled with annotation
@UseAdviceWith on Test class.
By enabling Advice mechanism it disables automatically Camel Context starting. It leads you to enable it manually in test.
camelContext.start(); // start CamelContext explicitly
// perform test - send a message into route
camelContext.stop(); // stop CamelContext explicitly
The debug log shows the use of advice.
A debug log of test is the following.
For tests taking good sense it is necessary to implement another case — if supervisor tells to skip a file. I set mock endpoint is expected to receive 0 messages (0 files expected to move into
/tmp/out folder). And I set the Camel Advice to put “SKIP” as the response of supervisor.
This test is green, be sure.
You can find my sources on GitHub.
I hope my story helps you to test your Camel routes better and more straightforward.