We can generate dynamic response using Response templates.
Step 1: Create WireMockRule using ResponseTemplateTransformer.
public WireMockRule wireMockRule = new WireMockRule(WireMockConfiguration.options().port(HTTP_SERVICE_PORT).httpsPort(HTTPS_SERVICE_PORT).notifier(new ConsoleNotifier(true)).extensions(new ResponseTemplateTransformer(true)));
Step 2: Create a response json using response template.
[
{
"id": 1,
"firstName": "{{request.query.empName}}",
"lastName": "Ponnam"
},
{
"id": 2,
"firstName": "Lakshman",
"lastName": "{{request.query.empName}}"
}
]
{{request.query.empName}}: Access the value associated with query parameter empName.
Step 3: Create a stub that return response from queryNameTemplate.json file.
wireMockRule.stubFor(get(urlPathEqualTo("/api/v1/employees/by-name/")).withQueryParam("empName", equalTo(nameSubStr)).willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json").withBodyFile("queryNameTemplate.json")));
Find the below working application.
Employee.java
package com.sample.app.model;
public class Employee {
private int id;
private String firstName;
private String lastName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String toString() {
return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + "]";
}
}
EmployeeApiException.java
package com.sample.app.exception;
public class EmployeeApiException extends RuntimeException {
private static final long serialVersionUID = 119874212393098L;
public EmployeeApiException(String msg) {
super(msg);
}
}
EmployeeService.java
package com.sample.app.service;
import java.util.List;
import com.sample.app.model.Employee;
public interface EmployeeService {
public List<Employee> emps();
public Employee byId(int id);
public List<Employee> containsName(String name);
public Employee addEmployee(Employee emp);
public Employee updateEmployee(int id, Employee emp);
public Employee deleteEmployee(int id);
}
EmployeeRestClient.java
package com.sample.app.service.impl;
import java.util.List;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import org.springframework.web.util.UriComponentsBuilder;
import com.sample.app.exception.EmployeeApiException;
import com.sample.app.model.Employee;
import com.sample.app.service.EmployeeService;
public class EmployeeRestClient implements EmployeeService {
private WebClient webClient;
public EmployeeRestClient(WebClient webClient) {
this.webClient = webClient;
}
@Override
public List<Employee> emps() {
return webClient.get().uri("api/v1/employees").retrieve().bodyToFlux(Employee.class).collectList().block();
}
@Override
public Employee byId(int id) {
try {
return webClient.get().uri("api/v1/employees/" + id).retrieve().bodyToMono(Employee.class).block();
}catch(WebClientResponseException e) {
throw new EmployeeApiException(e.getMessage() + "," + e.getRawStatusCode());
}
}
@Override
public List<Employee> containsName(String name) {
String uriToHit = UriComponentsBuilder.fromUriString("api/v1/employees/by-name/").queryParam("empName", name)
.buildAndExpand().toString();
return webClient.get().uri(uriToHit).retrieve().bodyToFlux(Employee.class).collectList().block();
}
@Override
public Employee addEmployee(Employee emp) {
return webClient.post().uri("api/v1/employees").syncBody(emp).retrieve().bodyToMono(Employee.class).block();
}
@Override
public Employee updateEmployee(int id, Employee emp) {
return webClient.put().uri("api/v1/employees/" + id).syncBody(emp).retrieve().bodyToMono(Employee.class)
.block();
}
@Override
public Employee deleteEmployee(int id) {
return webClient.delete().uri("api/v1/employees/" + id).retrieve().bodyToMono(Employee.class).block();
}
}
EmployeeRestClientTest.java
package com.sample.app.service;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl;
import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.web.reactive.function.client.WebClient;
import com.github.tomakehurst.wiremock.common.ConsoleNotifier;
import com.github.tomakehurst.wiremock.common.Json;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import com.github.tomakehurst.wiremock.extension.responsetemplating.ResponseTemplateTransformer;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.sample.app.exception.EmployeeApiException;
import com.sample.app.model.Employee;
import com.sample.app.service.impl.EmployeeRestClient;
public class EmployeeRestClientTest {
private static final int HTTP_SERVICE_PORT = 8888;
private static final int HTTPS_SERVICE_PORT = 9999;
private List<Employee> ALL_EMPLOYEES = new ArrayList<>();
private EmployeeRestClient empRestClient;
private String baseURI;
private static int idCounter = 1;
private static Employee buildEmployee(String firstName, String lastName) {
Employee emp = new Employee();
emp.setId(idCounter);
emp.setFirstName(firstName);
emp.setLastName(lastName);
idCounter++;
return emp;
}
@Before
public void initializeEmployees() {
Employee emp1 = buildEmployee("Deepak", "Moud");
Employee emp2 = buildEmployee("Srinivasa Rao", "Gumma");
Employee emp3 = buildEmployee("Purna Chandra", "Rao");
Employee emp4 = buildEmployee("Madhavi Latha", "Gumma");
Employee emp5 = buildEmployee("Raghava", "Reddy");
Employee emp6 = buildEmployee("Ramesh Chandra", "Dokku");
ALL_EMPLOYEES.addAll(Arrays.asList(emp1, emp2, emp3, emp4, emp5, emp6));
}
@Before
public void setup() {
baseURI = "http://localhost:" + wireMockRule.port() + "/";
WebClient webClient = WebClient.create(baseURI);
empRestClient = new EmployeeRestClient(webClient);
}
@Rule
public WireMockRule wireMockRule = new WireMockRule(
WireMockConfiguration.options().port(HTTP_SERVICE_PORT).httpsPort(HTTPS_SERVICE_PORT)
.notifier(new ConsoleNotifier(true)).extensions(new ResponseTemplateTransformer(true)));
@Test
public void allEmployeeForAnyURL() {
wireMockRule.stubFor(get(anyUrl()).willReturn(aResponse().withStatus(200)
.withHeader("Content-Type", "application/json").withBody(Json.write(ALL_EMPLOYEES))));
List<Employee> resultFromService = empRestClient.emps();
assertEquals(resultFromService.size(), 6);
}
@Test
public void allEmployeeForEactURLPath() {
wireMockRule.stubFor(get(urlPathEqualTo("/api/v1/employees")).willReturn(aResponse().withStatus(200)
.withHeader("Content-Type", "application/json").withBody(Json.write(ALL_EMPLOYEES))));
List<Employee> resultFromService = empRestClient.emps();
assertEquals(resultFromService.size(), 6);
}
@Test
public void getEmployeeById() {
Employee emp = new Employee();
emp.setId(Integer.MAX_VALUE);
emp.setFirstName("Chamu");
emp.setLastName("Gurram");
wireMockRule.stubFor(get(urlPathMatching("/api/v1/employees/[1-5]")).willReturn(
aResponse().withStatus(200).withHeader("Content-Type", "application/json").withBody(Json.write(emp))));
for (int i = 1; i < 6; i++) {
Employee resultEmp = empRestClient.byId(1);
assertNotNull(resultEmp);
assertEquals(Integer.MAX_VALUE, resultEmp.getId());
assertEquals("Chamu", resultEmp.getFirstName());
assertEquals("Gurram", resultEmp.getLastName());
}
}
@Test
public void allEmployeeFromFile() {
wireMockRule.stubFor(get(urlPathEqualTo("/api/v1/employees")).willReturn(aResponse().withStatus(200)
.withHeader("Content-Type", "application/json").withBodyFile("allEmployees.json")));
List<Employee> resultFromService = empRestClient.emps();
assertEquals(resultFromService.size(), 2);
Employee emp = resultFromService.get(0);
if (emp.getId() == 1) {
assertEquals("Ram", emp.getFirstName());
assertEquals("Ponnam", emp.getLastName());
} else if (emp.getId() == 2) {
assertEquals("Lakshman", emp.getFirstName());
assertEquals("Gurram", emp.getLastName());
}
}
@Test
public void getEmployeeByIdUsingResponseTemplate() {
wireMockRule.stubFor(get(urlPathMatching("/api/v1/employees/3")).willReturn(aResponse().withStatus(200)
.withHeader("Content-Type", "application/json").withBodyFile("employeeByIdTemplate.json")));
Employee resultEmp = empRestClient.byId(3);
assertNotNull(resultEmp);
assertEquals(3, resultEmp.getId());
assertEquals("Ram", resultEmp.getFirstName());
assertEquals("Ponnam", resultEmp.getLastName());
}
@Test(expected = EmployeeApiException.class)
public void getEmployeeByIdNotFound() {
int empId = 12345;
wireMockRule.stubFor(get(urlPathMatching("/api/v1/employees/" + empId))
.willReturn(aResponse().withStatus(404).withHeader("Content-Type", "application/json")));
empRestClient.byId(12345);
}
@Test(expected = EmployeeApiException.class)
public void getEmployeeByIdNotFoundReturnErrorPayloadFromFile() {
int empId = 12345;
wireMockRule.stubFor(get(urlPathMatching("/api/v1/employees/" + empId)).willReturn(
aResponse().withStatus(404).withHeader("Content-Type", "application/json").withBodyFile("404.json")));
empRestClient.byId(12345);
}
@Test
public void getEmployeesContainsNameViaQueryParam() {
List<Employee> employeesContainNameGurram = new ArrayList<>();
employeesContainNameGurram.add(buildEmployee("Bala Krishna", "Gurram"));
employeesContainNameGurram.add(buildEmployee("Gurram", "Srinu"));
String nameSubStr = "Gurram";
wireMockRule.stubFor(
get(urlPathEqualTo("/api/v1/employees/by-name/")).withQueryParam("empName", equalTo(nameSubStr))
.willReturn(aResponse().withStatus(200).withHeader("Content-Type", "application/json")
.withBody(Json.write(employeesContainNameGurram))));
List<Employee> resultFromService = empRestClient.containsName(nameSubStr);
assertEquals(resultFromService.size(), 2);
}
@Test
public void getEmployeesContainsNameViaResponseTemplate() {
String nameSubStr = "Kumar";
wireMockRule.stubFor(get(urlPathEqualTo("/api/v1/employees/by-name/"))
.withQueryParam("empName", equalTo(nameSubStr)).willReturn(aResponse().withStatus(200)
.withHeader("Content-Type", "application/json").withBodyFile("queryNameTemplate.json")));
List<Employee> emps = empRestClient.containsName(nameSubStr);
assertEquals(emps.size(), 2);
for (Employee emp : emps) {
if (emp.getId() == 1) {
assertEquals("Kumar", emp.getFirstName());
assertEquals("Ponnam", emp.getLastName());
} else if (emp.getId() == 2) {
assertEquals("Lakshman", emp.getFirstName());
assertEquals("Kumar", emp.getLastName());
}
}
}
}
Create __files directory in src/test/resources and define 'allEmployees.json', 'employeeByIdTemplate.json', 404.json, queryNameTemplate.json files.
allEmployees.json
[
{
"id": 1,
"firstName": "Ram",
"lastName": "Ponnam"
},
{
"id": 2,
"firstName": "Lakshman",
"lastName": "Gurram"
}
]
employeeByIdTemplate.json
{
"id": "{{request.path.[3]}}",
"firstName": "Ram",
"lastName": "Ponnam"
}
404.json
{
"timeStamp": "{{now}}",
"uri": "{{request.path}}",
"message": "Requested resource not found",
"errorCode": 404
}
queryNameTemplate.json
[
{
"id": 1,
"firstName": "{{request.query.empName}}",
"lastName": "Ponnam"
},
{
"id": 2,
"firstName": "Lakshman",
"lastName": "{{request.query.empName}}"
}
]
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample.app</groupId>
<artifactId>employee-rest-client</artifactId>
<version>1</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-jre8-standalone</artifactId>
<version>2.26.3</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Total project structure looks like below.
Run EmployeeRestClientTest.java to run junit test cases.
You can download complete working application from this link.
No comments:
Post a Comment