Cześć,
mam funkcjonalność, w której aplikacja komunikuje się z API Spotify w celu uzyskania access tokena dla użytkownika.
Chciałbym napisać test do tej funkcjonalności, korzystając z WireMocka. Mockuję odpowiedź API, zwracając JSON zapisany w pliku.
W teście chciałbym sprawdzić, czy metoda faktycznie zwraca poprawny access token.
Pomyślałem, że pobiorę access token
z odpowiedzi zwróconej przez metodę i porównam z access tokenem
ręcznie pobranym z pliku JSON. Czy takie podejście jest dobre?
@Test
void whenRetrieveToken_ReturnExpectedToken() throws IOException {
mockApiResponse(200, response);
Result <String> result = accessTokenHandler.retrieveSpotifyAccessToken("auth_code", generateJwtTokenForUser());
assertThat(result.data()).isEqualTo(expectedToken());
}
private void mockApiResponse(int statusCode, String response) {
wireMockServer.stubFor(post("/v1/spotify/auth/api/token")
.willReturn(aResponse()
.withStatus(statusCode)
.withHeader("Content-Type", "application/json")
.withBody(response)));
}
private String expectedToken() throws IOException {
String expectedToken;
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("spotify_access_token_response.json")) {
expectedToken = jsonFieldExtractor.getFieldValueFromJson(inputStream, "access_token", String.class);
}
return expectedToken;
}
public class JsonFieldExtractor {
private final ObjectMapper objectMapper;
public JsonFieldExtractor(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
public <T> T getFieldValueFromJson(InputStream inputStream, String fieldPath, Class<T> valueType) throws IOException {
JsonNode jsonNode = objectMapper.readTree(inputStream);
JsonNode fieldValue = jsonNode.at("/" + fieldPath.replace(".", "/"));
if (fieldValue.isMissingNode()) {
throw new IllegalArgumentException(String.format("Field '%s' not found in JSON input", fieldPath));
}
return objectMapper.treeToValue(fieldValue, valueType);
}
}