#spring-boot #okhttp #spring-webclient
Вопрос:
Я не могу отключить веб-клиент
WebClientConfig.java
public @Bean("oauthWebClient") WebClient oauthWebClient() {
return WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(
HttpClient.create().option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 1000)
.doOnConnected(connection -> connection.addHandlerLast(new ReadTimeoutHandler(10))
.addHandlerLast(new WriteTimeoutHandler(10)))))
.filter(logOAuthResponse()).baseUrl(oauthTokenUrl)
.defaultHeaders(headers -> {
headers.setBasicAuth(secretHeaderValue);
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
})
.defaultUriVariables(oauthUriVariables)
.build();
}
serviceUti.java
пакет com.test.stats.volts.busops.utils;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientRequestException;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.test.stats.volts.busops.exception.VoltsDataAccessException;
import com.test.stats.volts.busops.exception.MtnDataAccessNotRespondingException;
import com.test.stats.volts.busops.exception.VoltsDataAcessException;
import com.test.stats.volts.busops.exception.UnableToGetOAuthTokenException;
@Component("voltsDataAccessServiceUtil")
public class ServiceUtil {
private static final Logger logger = LoggerFactory.getLogger(ServiceUtil.class);
@Autowired
@Qualifier("voltsDataAccessWebClient")
WebClient voltsDataAccessClient;
@Autowired
@Qualifier("oauthWebClient")
WebClient oauthClient;
@Value("${volts.dataaccess.end.point.save-meeting}")
private String saveMeetingEndPoint;
@Value("${volts.dataaccess.oauth.header-key.name}")
private String oauthHeaderKeyName;
@Value("${volts.dataccess.oauth.response.token.key-name}")
private String oauthResponseTokenKeyName;
@Value("#{${volts.dataaccess.api.endpoints.default.uri-variables}}")
private Map<String, String> voltsDataAccessUriVariables;
@Autowired
ObjectMapper mapper;
@Value("#{${volts.dataaccess.oauth.uri-variables}}")
private Map<String, String> oauthUriVariables;
@Value("${volts.dataaccess.oauth.scope}")
private String oauthScope;
@Value("${volts.dataaccess.oauth.grant_type}")
private String grantType;
@Value("${volts.dataaccess.oauth.secret.header-name}")
private String secretHeaderName;
@Value("${volts.dataaccess.oauth.secret.header-value}")
private String secretHeaderValue;
@Value("${volts.dataaccess.end.point.fetch-meeting}")
private String fetchMeetingEndPoint;
@Value("${volts.dataaccess.query.param.api-key-value}")
private String apiKey;
@Retryable(maxAttempts = 2)
public String postOAuthToken() throws VoltsDataAccessException {
try {
String respEntity = oauthClient.post()
.uri(uriBuilder -> uriBuilder.queryParam("scope", oauthScope).queryParam("grant_type", grantType)
.build())
.headers(headers -> headers.setBasicAuth(secretHeaderValue))
.retrieve()
.bodyToMono(String.class)
.block();
if (respEntity == null)
throw new UnableToGetOAuthTokenException(
"Exception while fetching OAUthToken as response from OAUth service is null resposne body");
try {
return mapper.readValue(respEntity, ObjectNode.class).get(oauthResponseTokenKeyName).asText();
} catch (JsonProcessingException e) {
logger.error("Exception while pasring token from Oauth ", e);
throw new UnableToGetOAuthTokenException(
"Exception while fetching OAUthToken as response from OAUth service is null resposne body");
}
} catch (WebClientRequestException e) {
logger.error("Request Exception to OAUth: message {}", e.getMessage(), e);
logger.error("", e);
throw new VoltsDataAccessException(e.getMessage(), HttpStatus.REQUEST_TIMEOUT.value());
}
catch (WebClientResponseException e) {
throw new VoltsDataAccessException(e.getMessage(), e.getRawStatusCode());
}
}
@Retryable(value = VoltsDataAcessException.class)
public ResponseEntity<VoltsResp> postSaveMeetingDetails(SaveVoltsReq voltsReq)
throws VoltsDataAcessException {
try {
ResponseEntity<VoltsResp> resp = voltsDataAccessClient.post()
.uri(saveMeetingEndPoint, uri -> uri.queryParam("apikey", apiKey).build())
.headers(headers -> headers.setBearerAuth(postOAuthToken()))
.contentType(MediaType.APPLICATION_JSON).bodyValue(voltsReq).retrieve()
.toEntity(VoltsResp.class).block();
return resp;
} catch (WebClientRequestException e) {
throw new VoltsDataAcessException(e.getMessage(), HttpStatus.REQUEST_TIMEOUT.value());
} catch (WebClientResponseException e) {
throw new VoltsDataAcessException(e.getMessage(), e.getRawStatusCode());
}
}
}
Мои тестовые занятия
WebClienrTests.java
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.reactive.function.client.WebClient;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.test.stats.volts.busops.config.WebClientConfig;
import com.test.stats.volts.busops.utils.ServiceUtil;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
@SpringBootTest(classes = { ServiceUtil.class, WebClientConfig.class,
ObjectMapper.class })
@RunWith(SpringRunner.class)
class ServiceUtilTests {
public static MockWebServer mockServer = new MockWebServer();
@MockBean
WebClientConfig webClientCondfig;
@Autowired
ServiceUtil serviceUtil;
@MockBean(name = "oauthWebClient")
WebClient oauthClient;
@MockBean(name = "voltsDataAccessWebClient")
WebClient voltsDataAccessWebClient;
@BeforeEach
void startMockServer() throws Exception {
mockServer.start(9090);
oauthClient = WebClient.create(mockServer.url("/").url().toString());
}
@AfterEach
void stopMockServer() throws Exception {
mockServer.shutdown();
}
@Test
void testPostOAuth() throws Exception {
mockServer.enqueue(new MockResponse().setResponseCode(200).setBody("OAuthToken"));
String expected = serviceUtil.postOAuthToken();
assertThat(expected).isNotNull().isEqualTo("OAuthToken");
}
}
Когда я запускаю вышеуказанный тест, я получаю эту ошибку
java.lang.NullPointerException:
postAuthToken()
При установке заголовков .headers(headers -> headers.setBasicAuth(secretHeaderValue))
Пожалуйста, помогите, как высмеять все это
Комментарии:
1. Каковы ваши намерения в этом тесте? Напишите интеграционный тест для всего вашего приложения или протестируйте свой ServiceUtil отдельно? Пожалуйста, также добавьте весь раздел импорта для вашего теста. Похоже, вы смешиваете JUnit 4 и 5. Это может быть полезно для начала работы с модульным и интеграционным тестированием приложений Spring Boot .
2. @rieckpil Я отредактировал свой вопрос пожалуйста, проверьте сейчас, я на самом деле пытаюсь протестировать
postoauthToken()
методServiceUtil.java
, который бросает меняNulPOinterException
на настройку заголовков3. затем, пожалуйста, также добавьте сюда весь исходный код
ServiceUtil
класса, чтобы понять его зависимости. Пожалуйста, также убедитесь, что ваш код правильно отформатирован.4. Добавлено, пожалуйста, проверьте.
5. @rieckpil вам нужна дополнительная информация ?