Back to Repositories

Testing Spring Cloud Gateway Routing and Fallback Mechanisms in SpringCloudLearning

This test suite validates Spring Cloud Gateway functionality using WireMock and WebTestClient. It demonstrates API gateway routing, response handling, and fallback mechanisms in a Spring Cloud environment.

Test Coverage Overview

The test suite covers essential gateway functionality including HTTP request routing, response handling, and circuit breaker patterns.

  • Tests successful request routing with header validation
  • Verifies timeout handling and fallback mechanisms
  • Validates JSON response parsing and assertion
  • Tests integration with Hystrix circuit breaker

Implementation Analysis

The implementation uses Spring’s WebTestClient for reactive testing combined with WireMock for service virtualization. The testing approach leverages Spring Boot’s test configuration capabilities with automated WireMock setup.

  • Uses @AutoConfigureWireMock for mock service configuration
  • Implements reactive test patterns with WebTestClient
  • Utilizes Spring Runner for test lifecycle management

Technical Details

  • Spring Boot Test framework with RANDOM_PORT configuration
  • WireMock for HTTP service simulation
  • WebTestClient for reactive endpoint testing
  • JUnit 4 test runner
  • AssertJ for response assertions
  • Spring Cloud Contract WireMock integration

Best Practices Demonstrated

The test suite exemplifies robust microservice testing practices with proper separation of concerns and thorough endpoint validation.

  • Isolated test environment with mock services
  • Comprehensive response validation
  • Clear test arrangement with stub configuration
  • Effective use of reactive testing patterns
  • Proper timeout and fallback testing

forezp/springcloudlearning

sc-f-gateway-first-sight/src/test/java/gateway/ApplicationTest.java

            
//package gateway;
//
//import org.junit.Test;
//import org.junit.runner.RunWith;
//
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.test.context.SpringBootTest;
//import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
//import org.springframework.test.context.junit4.SpringRunner;
//import org.springframework.test.web.reactive.server.WebTestClient;
//
//import static com.github.tomakehurst.wiremock.client.WireMock.*;
//import static org.assertj.core.api.Assertions.*;
//
///**
// * @author Ryan Baxter
// */
//// tag::code[]
//@RunWith(SpringRunner.class)
//@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
//		properties = {"httpbin=http://localhost:${wiremock.server.port}"})
//@AutoConfigureWireMock(port = 0)
//public class ApplicationTest {
//
//	@Autowired
//	private WebTestClient webClient;
//
//	@Test
//	public void contextLoads() throws Exception {
//		//Stubs
//		stubFor(get(urlEqualTo("/get"))
//				.willReturn(aResponse()
//					.withBody("{\"headers\":{\"Hello\":\"World\"}}")
//					.withHeader("Content-Type", "application/json")));
//		stubFor(get(urlEqualTo("/delay/3"))
//			.willReturn(aResponse()
//				.withBody("no fallback")
//				.withFixedDelay(3000)));
//
//		webClient
//			.get().uri("/get")
//			.exchange()
//			.expectStatus().isOk()
//			.expectBody()
//			.jsonPath("$.headers.Hello").isEqualTo("World");
//
//		webClient
//			.get().uri("/delay/3")
//			.header("Host", "www.hystrix.com")
//			.exchange()
//			.expectStatus().isOk()
//			.expectBody()
//			.consumeWith(
//				response -> assertThat(response.getResponseBody()).isEqualTo("fallback".getBytes()));
//	}
//}
//// end::code[]