MockWebServer BasicAuth 与 Spring

问题描述

我需要通过调用外部 API 来进行测试,我执行以下操作:

  • 服务类:
public class BatchStatusClient {

    @Value("${batchStatusUpdate.username}")
    private String username;

    @Value("${batchStatusUpdate.password}")
    private String password;

    public BatchStatusClient(@Value("${batchStatusUpdate.endpoint}")
            String urlBatchStatusUpdate) {
        this.webClient = WebClient.create("urlBatchStatusUpdate");
    }

    public Mono<JsonNode> getToken(String uuid) {
        return this.webClient.post()
                .uri("/authorization")
                .headers(httpHeaders1 -> {
                    httpHeaders1.setBasicAuth(username,password);
                    httpHeaders1.add(REQUEST_ALLOW_ORIGIN,"*");
                    httpHeaders1.add(REQUEST_ALLOW_CREDENTIALS,"false");
                    httpHeaders1.add(HttpHeaders.CONTENT_TYPE,MediaType.APPLICATION_FORM_URLENCODED_VALUE);
                })
                .body(BodyInserters.fromFormData("grant_type",grantType))
                .retrieve()
                .bodyToMono(JsonNode.class);
    }
}

  • 测试类:
@TestPropertySource(locations = "classpath:/application-dev.yml")
@SpringBoottest()
@ExtendWith(SpringExtension.class)
@ActiveProfiles("dev")
@ContextConfiguration(classes = BatchStatusClient.class)
public class BatchStatusClientTest {
  
    private BatchStatusClient batchStatusClient;
    
    private static MockWebServer mockWebServer;
   
    @BeforeEach
    public void setup() throws IOException {
        mockWebServer = new MockWebServer();
        mockWebServer.start(9090);
        this.batchStatusClient = new BatchStatusClient(
                mockWebServer.url("/").toString());
    }

    @Afterall
    static void tearDown() throws IOException {
        mockWebServer.shutdown();
    }
    
    @Test
    public void test_getToken() throws Exception {
        String jsonString = "{\"access_token\": \"QB7VGhGtQWEXB3J98lIjF3\"}";
        ObjectMapper mapper = new ObjectMapper();
        JsonNode jn = mapper.readTree(jsonString);
    
        mockWebServer.enqueue(new MockResponse()
                .setBody(new ObjectMapper().writeValueAsstring(jn))
                .addHeader(HttpHeaders.CONTENT_TYPE,MediaType.APPLICATION_JSON_VALUE));
        Mono<JsonNode> result = batchStatusClient.getToken("123");
        System.out.println("result = " + result);
        assertEquals("QB7VGhGtQWEXB3J98lIjF",result.block().get("access_token").asText());
    }
}

但是当我运行测试时出现以下异常:

java.lang.IllegalArgumentException: Username must not be null
  at org.springframework.util.Assert.notNull(Assert.java:201)
  at org.springframework.http.HttpHeaders.encodeBasicAuth(HttpHeaders.java:1834)
  at org.springframework.http.HttpHeaders.setBasicAuth(HttpHeaders.java:770)
  at org.springframework.http.HttpHeaders.setBasicAuth(HttpHeaders.java:751)

我应该做任何额外的配置吗?

解决方法

通过这些修改,它对我有用:

BatchStatusClient 类:

public BatchStatusClient(@Value("${batchStatusUpdate.endpoint}")
                                 String urlBatchStatusUpdate,@Value("${batchStatusUpdate.username}") String username,@Value("${batchStatusUpdate.password}") String password){
    this.webClient = WebClient.create(urlBatchStatusUpdate);
    this.username = username;
    this.password = password;

在设置方法中:

@BeforeEach
void setup() throws IOException {
    this.mockWebServer = new MockWebServer();
    this.batchStatusClient = new BatchStatusClient(
            mockWebServer.url("/").toString(),"username","password"
    );
}