Back to Repositories

Testing Spring Cloud Gateway Filters and Circuit Breakers in SpringCloudLearning

This test suite validates Spring Cloud Gateway filters and circuit breaker functionality in a microservices environment. It focuses on testing HTTP request routing, response handling, and fallback mechanisms using WireMock for service simulation.

Test Coverage Overview

The test suite provides comprehensive coverage of Spring Cloud Gateway’s core functionality.

Key areas tested include:
  • HTTP GET request routing and response handling
  • Custom header manipulation and verification
  • Timeout scenarios with delayed responses
  • Circuit breaker fallback behavior
  • JSON response body validation

Implementation Analysis

The testing approach utilizes Spring Boot Test framework with WebTestClient for reactive API testing. WireMock stubs simulate external service endpoints, enabling controlled testing of gateway behavior. The implementation leverages Spring Runner for test execution and employs declarative test configurations through annotations.

Technical patterns include:
  • Reactive web testing with WebTestClient
  • Mock service endpoints using WireMock
  • Declarative test configuration with @SpringBootTest
  • JSON path assertions for response validation

Technical Details

Testing tools and configuration:
  • JUnit 4 test framework
  • Spring Boot Test 2.x
  • WireMock for service virtualization
  • WebTestClient for reactive endpoints
  • AssertJ for assertions
  • Random port allocation for test server
  • Automated WireMock configuration

Best Practices Demonstrated

The test implementation showcases several testing best practices for Spring Cloud Gateway applications.

Notable practices include:
  • Isolation of external dependencies using WireMock
  • Clear test arrangement with stub setup
  • Explicit verification of response status and content
  • Proper error scenario testing
  • Clean separation of test configuration and execution
  • Effective use of Spring Boot Test annotations

forezp/springcloudlearning

sc-f-gateway-filter/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[]