March 17, 2016 | Software Consultancy
In order to be able to regularly release an application, your automated tests must be set up to give you fast and reliable feedback loop. If bugs are only found during a long and expensive multi-service or end-to-end test run, it can be a hinderance to fast delivery. Unfortunately I have often seen this problem in development environments: a huge suite of clunky, flaky and slow end-to-end tests which test the full functionality of the application as opposed to being more lightweight and reflecting basic user journeys. This produces the “ice cream cone” anti-pattern of test coverage, where unit tests aren’t providing the kind of coverage and feedback they need to.
WRITTEN BY
This has been reposted from Spectolabs.
There are many reasons for this – developer laziness, a lack of understanding of a build’s importance by the business – or more technical issues such as the difficulties involved in stubbing the architectural boundaries of an application or service. You can’t know that everything works together until everything is deployed together.
Following on from the previous blog post, I’ve created a Hoverfly JUnit Rule which enables you to quickly and reliably simulate an external API in your Java unit / integration tests.
Hoverfly is a lightweight proxy which can be used to “capture” and “virtualize” (and thus simulate) external services. It also allows you to use custom middleware to modify requests and responses on demand, allowing for easier testing of resilience patterns in your environment. It’s written in Go, so it is fast and light on resource consumption, and because it is a proxy it is non-intrusive (meaning you don’t have to explicitly point to a stub webserver). As a single binary, it’s designed to be used in any stack across the whole test pipeline from unit testing to multi-service testing to end-to-end testing.
This JUnit rule wraps the Hoverfly binary and fits it into the Java unit testing tier, allowing for more reliable API simulation at the lowest level. The source code for the rule is available on GitHub.
The rule is available in Maven Central:
io.specto
hoverfly-junit
0.1.1
Hoverfly stores request-to-response mappings as json. This .json
is either created by Hoverfly as it “captures” communication with an external service, or it can be created manually. The .json
can be exported from and imported into Hoverfly.
You can declare the rule as follows:
@Rule
public HoverflyRule hoverflyRule = HoverflyRule.buildFromClassPathResource("test-service.json").build();
The rule takes a convention over configuration approach, meaning this is all you need to do to get it working. Behind the scenes it will:
.json
into its database.An example test may look as follows:
public class HoverflyRuleTest {
@ClassRule
public static HoverflyRule hoverflyRule = HoverflyRule.buildFromClassPathResource("test-service.json").build();
private RestTemplate restTemplate;
@Before
public void setUp() {
restTemplate = new RestTemplate();
}
@Test
public void shouldBeAbleToMakeABooking() throws URISyntaxException {
// Given
final RequestEntity bookFlightRequest = RequestEntity.post(new URI("http://www.my-test.com/api/bookings"))
.contentType(APPLICATION_JSON)
.body("{\"flightId\": \"1\"}");
// When
final ResponseEntity bookFlightResponse = restTemplate.exchange(bookFlightRequest, String.class);
// Then
assertThat(bookFlightResponse.getStatusCode()).isEqualTo(CREATED);
assertThat(bookFlightResponse.getHeaders().getLocation()).isEqualTo(new URI("http://localhost/api/bookings/1"));
}
}
(Please feel free to visit the project on GitHub if you wish to contribute!)
What if when building a service, the pipeline also created a virtualized version of the service as an artefact? This could be handy for consumers who want to test against your service – simply give them the .json
to import into Hoverfly and they can start testing. As somebody who has spent alot of time working with microservices I know this could have been beneficial in some of the CI pipelines I’ve worked with – run the tests, have the requests intercepted, produce a simulation, make it available to others. It would have saved alot of time spent stubbing services in the consumer tests. This approach tends to be quite error-prone – meaning you don’t encounter failures until deploying into an environment where there’s communication with the real service.
With these things in mind, I thought there would be value in producing Hoverfly .json
from Java integration tests which may not use real http. MockMvc is a popular testing framework which only simulates http, so in order to get the requests intercepted, a servlet filter has been created which outputs them to a .json
file. It can be found in Maven Central:
io.specto
hoverfly-jrecorder
0.1.1
Simply add the filter as an interceptor in your MockMvc test. It will output everything with the given base URL to the given path on the filesystem. This json can then be imported into Hoverfly for testing.
private static HoverflyFilter hoverflyFilter = new HoverflyFilter("www.my-test.com", "generated/hoverfly.json");
@Before
public void setUp() {
this.mockMvc = webAppContextSetup(webApplicationContext)
.addFilter(hoverflyFilter)
.build();
}
This could fit very nicely into your CI pipeline, producing the virtualization on every build. The .json
files could be uploaded to a repository such as Nexus, GitHub or some other location. The idea is that these files would be globally accessible, so the same test data could be used across the entire development stack. That’s one of the main advantages of Hoverfly: it’s possible for it to “fit” everywhere, therefore allowing you to re-use the service same behaviour across every tier of testing. Its also worth bearing in mind that if your tests use real http, you could use Hoverfly in “capture” mode to produce the .json
as an alternative.
Please visit the project on GitHub if you wish to contribute.
Hoverfly has value across all tiers of testing, from unit to end-to-end testing. Here we have focused primarily on Java Unit / Integration testing, but because data can easily imported into Hoverfly as .json
it shows how interoperable it can be. It has also been demonstrated that service virtualization or “API simulation” could arguably be part of a build pipeline, allowing components to be tested easily by any number of consumers who use Hoverfly.
This blog is written exclusively by the OpenCredo team. We do not accept external contributions.
Agile India 2022 – Systems Thinking for Happy Staff and Elated Customers
Watch Simon Copsey’s talk from the Agile India Conference on “Systems Thinking for Happy Staff and Elated Customers.”Lean-Agile Delivery & Coaching Network and Digital Transformation Meetup
Watch Simon Copsey’s talk from the Lean-Agile Delivery & Coaching Network and Digital Transformation Meetup on “Seeing Clearly in Complexity” where he explores the Current…When Your Product Teams Should Aim to be Inefficient – Part 2
Many businesses advocate for efficiency, but this is not always the right goal. In part one of this article, we explored how product teams can…