반응형
운영 환경에서 사용하기
build.gradle.kts
extra["springCloudVersion"] = "2022.0.4"
dependencies {
...
implementation("org.springframework.cloud:spring-cloud-starter-contract-stub-runner")
}
dependencyManagement {
imports {
mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
}
}
WireMockConfig
@Configuration
public class WireMockConfig {
private final Logger log = LoggerFactory.getLogger(WireMockConfig.class);
@Bean(initMethod = "start", destroyMethod = "stop")
public WireMockServer wireMockServer() throws IOException {
log.info("[WIRE_MOCK_CONFIG] start");
WireMockServer wireMockServer = new WireMockServer(WireMockSpring.options().disableRequestJournal().port(19090));
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resolver.getResources("wiremock/**/*.json");
for (Resource resource : resources) {
log.info("[WIRE_MOCK_CONFIG] jsonFilePath : {}", resource.getURL().getPath());
wireMockServer.addStubMapping(StubMapping.buildFrom(IOUtils.toString(resource.getInputStream())));
}
log.info("[WIRE_MOCK_CONFIG] finish");
return wireMockServer;
}
}
Mocking
JavaConfig를 활용한 방법
@RequiredArgsConstructor
@Configuration
public class DemoApiMocking {
private final WireMockServer wireMockServer;
@PostConstruct
public void mocking() {
wireMockServer.stubFor(
WireMock.post(WireMock.urlPathMatching("/api/demo/(.*?)"))
.withRequestBody(WireMock.equalToJson("{\"name\": \"john\"}"))
.willReturn(
WireMock.aResponse()
.withStatus(200)
.withHeader("Content-Type", MediaTypes.APPLICATION_JSON)
.withBody("{\"message\": \"Hi, john\"}")
)
);
}
}
json 파일을 활용한 방법
- 경로 : ~/src/main/resources/wiremock/demo-api-mocking.json
{ "request": { "urlPathPattern": "/api/demo/(.*?)", "method": "POST", "bodyPatterns": [ { "equalToJson": { "name": "john" } } ] }, "response": { "status": 200, "headers": { "Content-Type": "application/json" }, "jsonBody": { "message": "Hi, john" } } }
Test
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> result = restTemplate.exchange("http://localhost:19090/api/demo/john", HttpMethod.POST, new HttpEntity<>("{\"name\": \"john\"}"), String.class);
String body = result.getBody();
System.out.println(body); // {"message": "Hi, john"}
참고
- 요청 매칭 예시 : https://wiremock.org/docs/request-matching
테스트 케이스에서 사용하기
src/test/resources/application-unittest.properties
demo.url=http://localhost:${wiremock.server.port}
Java 코드로 모킹하여 테스트
WireMockTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureWireMock(port = 0)
@ActiveProfiles("unittest")
public class WireMockTest {
@Value("${demo.url}")
private String demoUrl;
@Test
public void demo() throws Exception {
// WireMock.stubFor(
// WireMock.get(WireMock.urlPathEqualTo("/api/v1/demo"))
// .willReturn(WireMock.aResponse()
// .withStatus(HttpStatus.OK.value())
// .withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)
// .withBody(Files.readString(ResourceUtils.getFile("classpath:payload/demo-body.json").toPath()))
// )
// );
WireMock.stubFor(
WireMock.get(WireMock.urlPathEqualTo("/api/v1/demo"))
.willReturn(WireMock.aResponse()
.withStatus(HttpStatus.OK.value())
.withHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)
.withBody("{\"name\":\"tyler\", \"age\": 50}")
)
);
RestTemplate restTemplate = new RestTemplate();
Map result = restTemplate.getForObject(demoUrl + "/api/v1/demo", Map.class);
System.out.println(result.get("name")); // tyler
System.out.println(result.get("age")); // 50
}
}
json 파일로 모킹하여 테스트
src/test/resources/stubs/demo-v1.json
{
"request": {
"method": "GET",
"url": "/api/v1/demo"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"jsonBody": {
"name": "tyler",
"age": 50
}
}
}
WireMockTest
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureWireMock(port = 0, stubs = "classpath:/stubs")
@ActiveProfiles("unittest")
public class WireMockTest {
@Value("${demo.url}")
private String demoUrl;
@Test
public void demo() {
RestTemplate restTemplate = new RestTemplate();
Map result = restTemplate.getForObject(demoUrl + "/api/v1/demo", Map.class);
System.out.println(result.get("name")); // tyler
System.out.println(result.get("age")); // 50
}
}
반응형
'Development > Spring' 카테고리의 다른 글
[Spring] Elasticsearch (0) | 2024.01.01 |
---|---|
[Spring] 헥사고날 아키텍처(Hexagonal Architecture) (2) | 2023.11.23 |
[Spring] SpEL (0) | 2023.08.09 |
[Spring] actuator (0) | 2021.11.27 |
[Spring] Scheduler Lock (0) | 2021.11.25 |