DZone
Integration Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Integration Zone > Using WireMock to Mock Underlying Services for REST Testing in Spring Boot

Using WireMock to Mock Underlying Services for REST Testing in Spring Boot

Learn how the WireMock simulator can be used to mock an API response while testing your REST services developed in Spring Boot.

Deepak Tyagi user avatar by
Deepak Tyagi
·
Oct. 23, 17 · Integration Zone · Tutorial
Like (15)
Save
Tweet
73.65K Views

Join the DZone community and get the full member experience.

Join For Free

WireMock is a simulator for HTTP-based APIs and can be used to mock an API response in case of REST services development and testing. In this article, we will focus on how WireMock can be used to mock an API response while testing REST service that you are developing in SpringBoot. In this way, you can simulate scenarios for which getting test data is time-consuming in the real world. I used it in integration testing Gateway APIs to mock API responses for the underlying services that we were using.

Including WireMock in Project as a Dependency

As mentioned by http://www.wiremock.org, it is currently recommended that you use the standalone JAR as a dependency with Spring Boot projects. This avoids a conflict over the Jetty version.

<dependency>
      <groupId>com.github.tomakehurst</groupId>
      <artifactId>wiremock-standalone</artifactId>
      <version>2.6.0</version>      
</dependency>

Writing the Integration Test

JUnit now has a Classrule for WireMock to handle the lifecycle and setup/tear-down tasks.

@ClassRule public static WireMockRule wireMockRule = new WireMockRule( options().port(8090).httpsPort(8443).notifier(new ConsoleNotifier(true)));

With this, WireMock now runs at port 8090/8443 and can serve HTTP(s) request on that port. Also set up ConsoleNotifier to see all the WireMock notifications (data available/returned) on the console. Any API that you want to mock has to point to WireMock at the specified port, so that data is now served from WireMock. For example, if your service runs at http://www.someserver.com/api/path/resource , then you have to change it in your testing tohttp://localhost:8080/api/path/resource .

Spring provides an easy way to achieve this with "Spring Profile." You can set your "Test" profile in application.yaml with all the APIs that have to be mocked to point to the WireMock port.

spring:
    profiles: integration
clients:
  blah:
    server: http://localhost:8090
resource: /api/path/v1.0/resourcename
  otherblah:
      server: http://localhost:8090

Now, when you write your integration test in Spring, you specify a particular profile to use.

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = YourApplication.class, 
                webEnvironment=WebEnvironment.DEFINED_PORT)
@ActiveProfiles("integration")
@Profile("integration")
public class YourWiremockTest {

Before you write your actual test, you can set up the response data for the underlying APIs that you want to use mock, record, and replay kind of statements:

wireMockRule.stubFor(post(urlPathMatching("/api/path/v1.0/resourcename"))
  .withRequestBody(containing("\"somethinginheader\":\"50cca0e4-69ea-4247\""))
  .willReturn(aResponse()
  .withStatus(200)
  .withHeader("Content-Type", APPLICATION_JSON)
  .withBody(fileToJSON("datafile.with.data.json"))));

Let's take a look at these statements.

Stub for wireMockRule.stubFor(post(urlPathMatching("/api/path/v1.0/resourcename"))

Match on criteria:withRequestBody(containing("\"somethinginheader\":\"50cca0e4-69ea-4247\""))

Specify the header and HTTP code for the response:.willReturn(aResponse() .withStatus(200) .withHeader("Content-Type", APPLICATION_JSON)

Last, the response withBody(fileToJSON("datafile.with.data.json"))))

Remaining task is executing the functionality under test and assertions

Response response = someController.functionalityUnderTest();
//Check response status
Assert.assertTrue(response.getStatus()==200);
//Check return type
Assert.assertTrue(response.getEntity() != null);
Assert.assertTrue(response.getEntity() instanceof  SomeTypeOfList);

CI/CD Integration

These tests can be included in a Jenkins (or any other CI tool) build to run with or without the code build (better to run as a separate build) and it runs like any other JUnit test case.

Share your experience with using WireMock.

Spring Framework REST Web Protocols Spring Boot integration test Test data

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • What SREs Can Learn From the Atlassian Nightmare Outage of 2022
  • Modernize Legacy Code in Production: Rebuild Your Airplane Midflight Without Crashing
  • Top 20 Git Commands With Examples
  • The Evolution of Configuration Management: IaC vs. GitOps

Comments

Integration Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo