Skip to content

Instantly share code, notes, and snippets.

@ru-rocker
Last active April 8, 2024 17:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ru-rocker/be9dce472ac7b059e04c1492d39ac2cc to your computer and use it in GitHub Desktop.
Save ru-rocker/be9dce472ac7b059e04c1492d39ac2cc to your computer and use it in GitHub Desktop.
SpringWebFlux Unit Test with MockWebServer from OkHttp
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>mockwebserver</artifactId>
<version>4.12.0</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.netty/netty-resolver-dns-native-macos -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-resolver-dns-native-macos</artifactId>
<version>4.1.68.Final</version>
<scope>test</scope>
<classifier>osx-aarch_64</classifier>
</dependency>
@Service
public class TokenValidatorServiceImpl implements TokenValidatorService {
private String fileAttUrlPath;
private String fileAttRoute;
@Autowired
private ClientProperties clientProperties;
private final WebClient.Builder webClientBuilder;
private static final Logger LOG = LoggerFactory.getLogger(TokenValidatorServiceImpl.class);
public TokenValidatorServiceImpl(WebClient.Builder webClientBuilder) {
this.webClientBuilder = webClientBuilder;
}
@Override
public Mono<TokenInfo> validateToken(String tokenBearer) {
String url = URLUtil.buildFullUrl(StringUtil.strConcat(fileAttRoute, fileAttUrlPath));
// @formatter:off
return webClientBuilder
.build()
.post()
.uri(url)
.accept(MediaType.APPLICATION_JSON)
.header(clientProperties.getAuthorizationHeader(), tokenBearer)
.body(BodyInserters.fromValue("parameters"))
.retrieve()
.bodyToMono(String.class)
.onErrorMap(throwable -> new RestClientException(throwable.getMessage()))
.flatMap(response -> {
LOG.info("Response : {}", response);
TokenInfo tokenInfo = JsonUtil.getObjectFromJson(response, TokenInfo.class);
return validateResponse(tokenBearer, tokenInfo);
});
// @formatter:on
}
private Mono<TokenInfo> validateResponse(final String tokenBearer, final TokenInfo tokenInfo) {
if (tokenInfo == null || tokenInfo.getUser() == null) {
return Mono.error(new TokenNotFoundException("Invalid token. Please login again !!!"));
}
Integer responseCode = tokenInfo.getResponseCode();
LOG.debug("Token Info : {} {}", tokenInfo, responseCode);
if (responseCode == null
|| responseCode != HttpStatus.OK.value()
|| StringUtils.isEmpty(tokenInfo.getUserGroups())) {
return Mono.error(new RoleNotFoundException(
"Either Insufficient authentication details or No role/group is mapped to the user"));
}
return Mono.just(tokenInfo);
}
}
public class TokenValidatorServiceImplTest {
@Mock
ClientProperties clientProperties;
@InjectMocks
private TokenValidatorServiceImpl tokenValidatorService;
private static MockWebServer mockWebServer;
private AutoCloseable autoCloseable;
@BeforeEach
void setUp() {
mockWebServer = new MockWebServer();
HttpUrl url = mockWebServer.url("/");
WebClient.Builder mockedWebClient = WebClient.builder().baseUrl(url.toString());
tokenValidatorService = new TokenValidatorServiceImpl(mockedWebClient);
ReflectionTestUtils.setField(tokenValidatorService, "fileAttRoute", String.format("localhost:%d", url.port()));
ReflectionTestUtils.setField(tokenValidatorService, "fileAttUrlPath", "/");
autoCloseable = MockitoAnnotations.openMocks(this);
}
@AfterEach
void tearDown() throws Exception {
mockWebServer.close();
autoCloseable.close();
}
@Test
public void testValidateTokenInfo_TokenValid() {
// Given
String token = "Authorization Bearer 1234";
// When
mockWebServer.enqueue(new MockResponse()
.setResponseCode(HttpStatus.OK.value())
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.setBody(getMockedTokenValidResponse()));
when(clientProperties.getAuthorizationHeader()).thenReturn("test");
Mono<TokenInfo> result = tokenValidatorService.validateToken(token);
// Then
StepVerifier.create(result)
.expectNextMatches(tokenInfo -> {
boolean flag;
flag = tokenInfo.getFullname().equals("Bon Jovi");
flag = flag && tokenInfo.getUser().equals("Feli");
flag = flag && tokenInfo.getToken().equals("TOKEN");
flag = flag && tokenInfo.getResponseCode() == 200;
flag = flag && tokenInfo.getUserGroups().equals("Admin");
flag = flag && tokenInfo.getTokenStatus().equals("Active");
return flag;
})
.verifyComplete();
}
@Test
public void testValidateTokenInfo_TokenInValid_TokenInfoNull() {
// Given
String token = "Authorization Bearer 1234";
// When
mockWebServer.enqueue(new MockResponse()
.setResponseCode(HttpStatus.OK.value())
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.setBody("patience"));
when(clientProperties.getAuthorizationHeader()).thenReturn("test");
Mono<TokenInfo> result = tokenValidatorService.validateToken(token);
// Then
StepVerifier.create(result).expectError(TokenNotFoundException.class).verify();
}
@Test
public void testValidateTokenInfo_TokenInValid_TokenInfoUserIsEmpty() {
// Given
String token = "Authorization Bearer 1234";
// When
mockWebServer.enqueue(new MockResponse()
.setResponseCode(HttpStatus.OK.value())
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.setBody(getMockedTokenInvalidResponseUserIsEmpty()));
when(clientProperties.getAuthorizationHeader()).thenReturn("test");
Mono<TokenInfo> result = tokenValidatorService.validateToken(token);
// Then
StepVerifier.create(result).expectError(TokenNotFoundException.class).verify();
}
@Test
public void testValidateTokenInfo_TokenInValid_TokenInfoHttpStatusIsEmpty() {
// Given
String token = "Authorization Bearer 1234";
// When
mockWebServer.enqueue(new MockResponse()
.setResponseCode(HttpStatus.OK.value())
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.setBody(getMockedTokenInvalidResponseHttpStatusIsEmpty()));
when(clientProperties.getAuthorizationHeader()).thenReturn("test");
Mono<TokenInfo> result = tokenValidatorService.validateToken(token);
// Then
StepVerifier.create(result).expectError(RoleNotFoundException.class).verify();
}
@Test
public void testValidateTokenInfo_TokenInValid_TokenInfoHttpStatusIsNot200() {
// Given
String token = "Authorization Bearer 1234";
// When
mockWebServer.enqueue(new MockResponse()
.setResponseCode(HttpStatus.OK.value())
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.setBody(getMockedTokenInvalidResponseHttpStatusIsNot200()));
when(clientProperties.getAuthorizationHeader()).thenReturn("test");
Mono<TokenInfo> result = tokenValidatorService.validateToken(token);
// Then
StepVerifier.create(result).expectError(RoleNotFoundException.class).verify();
}
@Test
public void testValidateTokenInfo_TokenInValid_TokenInfo_Resp200UserGroupNull() {
// Given
String token = "Authorization Bearer 1234";
// When
mockWebServer.enqueue(new MockResponse()
.setResponseCode(HttpStatus.OK.value())
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.setBody(getMockedTokenInvalidResponseHttpStatusIs200UserGroupNull()));
when(clientProperties.getAuthorizationHeader()).thenReturn("test");
Mono<TokenInfo> result = tokenValidatorService.validateToken(token);
// Then
StepVerifier.create(result).expectError(RoleNotFoundException.class).verify();
}
private String getMockedTokenValidResponse() {
return "{\"responseCode\":200,\"user\":\"Feli\",\"userGroups\":\"Admin\",\"token\":\"TOKEN\","
+ "\"tokenStatus\":\"Active\",\"fullname\":\"Bon Jovi\"}";
}
private String getMockedTokenInvalidResponseUserIsEmpty() {
return "{\"token\":\"TOKEN\",\"tokenStatus\":\"Active\",\"fullname\":\"Bon Jovi\"}";
}
private String getMockedTokenInvalidResponseHttpStatusIsEmpty() {
return "{\"token\":\"TOKEN\",\"tokenStatus\":\"Active\",\"user\":\"Feli\",\"fullname\":\"Bon Jovi\"}";
}
private String getMockedTokenInvalidResponseHttpStatusIsNot200() {
return "{\"responseCode\":204,\"token\":\"TOKEN\",\"tokenStatus\":\"Active\","
+ "\"user\":\"Feli\",\"fullname\":\"Bon Jovi\"}";
}
private String getMockedTokenInvalidResponseHttpStatusIs200UserGroupNull() {
return "{\"responseCode\":200,\"token\":\"TOKEN\",\"tokenStatus\":\"Active\","
+ "\"user\":\"Feli\",\"fullname\":\"Bon Jovi\"}";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment