Testing code that consume REST API(s) can sometimes presents some difficulties, as you can face allot of constraints when dealing with them, like API rates limit, authentication tokens and passwords sharing, API availability, sandbox that expire or API’s cost that may be high…
As a developer you don’t want to care about all that, as all what you want to achieve is writing some good tests for your code logic. This is why, having the possibility to easily mock the API response is trivial.
The component framework provides an API simulation tool that make it easy to write unit tests. In this tutorial we will show how to use it in unit tests.
In this previous tutorial, we have created a component that consume Zendesk Search API. We will add some unit tests for it.
We have added 4 tickets that have the status open to our Zendesk test instance. that we will use in our tests |
In our tutorial we will use some concept from component junit testing.
You can refer to this page to read about the SimpleComponentRule
…
L’est create a first unit test that will perform a real http request to Zendesk Search API instance. You can read how to create a simple unit test in this tutorial
public class SearchTest {
@ClassRule
public static final SimpleComponentRule component = new SimpleComponentRule("component.package");
@Test
public void searchQuery() {
// Initiating the component test configuration (1)
BasicAuth basicAuth = new BasicAuth("https://instance.zendesk.com", "username", "password");
final SearchQuery searchQuery = new SearchQuery(basicAuth, "type:ticket status:open", "created_at", "desc");
// We convert our configuration instance to URI configuration (2)
final String uriConfig = SimpleFactory.configurationByExample()
.forInstance(searchQuery)
.configured().toQueryString();
// We create our job test pipeline (3)
Job.components()
.component("search", "zendesk://search?" + uriConfig)
.component("collector", "test://collector")
.connections()
.from("search").to("collector")
.build()
.run();
final List<JsonObject> res = component.getCollectedData(JsonObject.class);
assertEquals(4, res.size());
}
}
1 | We initiate our authentication configuration using zendesk instance’s url and credentials. We also initiate our search query configuration. We want to get all the open ticket order by the creation date in a descendant order. |
2 | Here we perform a simple conversion of our configuration to URI format, that we will use in the job test pipeline,
using SimpleFactory class provided by the component framework. Read more about job pipeline. |
3 | We create our job test pipeline. this is a simple pipeline that will execute our search component and redirect the result
to the test collector component that will collect the search result.
We execute the pipeline.
Then, We get the job result and we ensure that we have received the 4 tickets. You can also check that the retrieved tickets have the open status. |
So here we have created a complete working test. the test is performing real http request to our zendesk instance. but we may don’t want do that every time on the development environment. We may want to execute real http request only on an integration environment and on development environment use some mocked result to develop faster or for any other reasons.
Now we will transform this unit test to a mocked test that will use only mocked response of zendesk Search API. To do that you will need to add 2 junit rules provided by the component framework.
-
JUnit4HttpApi
- this rule will start a simulation server that will act as a proxy and catch all the http requests performed inside the tests. This simulation server (proxy) have 2 modes :-
capture : this mode will forward the captured http request to the real server and capture there response.
-
simulation : this mode will return a mocked response from the already captured responses. This rule need to be added as a class rule
-
-
JUnit4HttpApi
- this rule have a reference to the first one and it role is to configure the simulation server for every unit test. it provide the simulation server by the running test context. This rule need to be added as a simple (method) rule.
Let’s add those 2 rules to our test to make it run in a simulation mode.
public class SearchTest {
@ClassRule
public static final SimpleComponentRule component = new SimpleComponentRule("component.package");
private final MavenDecrypter mavenDecrypter = new MavenDecrypter();
@ClassRule
public static final JUnit4HttpApi API = new JUnit4HttpApi() (1)
.activeSsl(); (2)
@Rule
public final JUnit4HttpApiPerMethodConfigurator configurator = new JUnit4HttpApiPerMethodConfigurator(API); (3)
@Test
public void searchQuery() {
// the exact same code as above
}
1 | As described above, we create and start a simulation server for this test class. |
2 | As the API that we consume use ssl, we need to activate ssl on or simulation server by simply calling the activeSsl() method. |
3 | We add our simulation server configuration provider. that will provide the test context to the simulation server. |
We almost done,
Now we need to run our test in capture mode to catch the real API responses to be able to use them later in the simulated mode.
To do that, we will have to set an environment variable talend.junit.http.capture
to true
.
This will tel the simulation server to run in a capture mode.
The captured response will be saved into resources/talend.testing.http
package in a json format, then reused to perform API simulation.
Now you know how to easily mock your component that consume REST API.