Testing code that consumes REST APIs can sometimes present many constraints: API rate limit, authentication token and password sharing, API availability, sandbox expiration, API costs, and so on.
As a developer, it becomes critical to avoid those constraints and to be able to easily mock the API response.
The component framework provides an API simulation tool that makes it easy to write unit tests.
This tutorial shows how to use this tool in unit tests. As a starting point, the tutorial uses the component that consumes Zendesk Search API and that was created in a previous tutorial. The goal is to add unit tests for it.
For this tutorial, four tickets that have the open status have been added to the Zendesk test instance used in the tests. |
To learn more about the testing methodology used in this tutorial, refer to Component JUnit testing.
Creating the unit test
Create a unit test that performs a real HTTP request to the Zendesk Search API instance. You can learn 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 | Initiating:
|
2 | Converting the configuration to a URI format that will be used in the job test pipeline,
using the SimpleFactory class provided by the component framework. Read more about job pipeline. |
3 | Creating the job test pipeline. The pipeline executes the search component and redirects the result to the test collector component, that collects the search result.
The pipeline is then executed.
Finally, the job result is retrieved to check that the four tickets have been received. You can also check that the tickets have the open status. |
The test is now complete and working. It performs a real HTTP request to the Zendesk instance.
Transforming the unit test into a mocked test
As an alternative, you can use mock results to avoid performing HTTP requests every time on the development environment. The real HTTP requests would, for example, only be performed on an integration environment.
To transform the unit test into a mocked test that uses a mocked response of the Zendesk Search API:
-
Add the two following JUnit rules provided by the component framework.
-
JUnit4HttpApi
: This rule starts a simulation server that acts as a proxy and catches all the HTTP requests performed in the tests. This simulation server has two modes :-
capture : This mode forwards the captured HTTP request to the real server and captures the response.
-
simulation : this mode returns a mocked response from the responses already captured. This rule needs to be added as a class rule.
-
-
JUnit4HttpApi
: This rule has a reference to the first rule. Its role is to configure the simulation server for every unit test. It passes the context of the running test to the simulation server. This rule needs to be added as a simple (method) rule.
-
Example to 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 | Creating and starting a simulation server for this test class. |
2 | Activating SSL on the simulation server by calling the activeSsl() method. This step is required because the consumed API uses SSL. |
3 | Adding the simulation server configuration provider that provides the test context to the simulation server. |
-
Make the test run in capture mode to catch the real API responses that can be used later in the simulated mode.
To do that, set a newtalend.junit.http.capture
environment variable totrue
. This tells the simulation server to run in a capture mode.
The captured response is saved in the resources/talend.testing.http
package in a JSON format, then reused to perform the API simulation.