0

I need to do tests by calling an external API, where I do the following:

  • Service Class:
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);
    }
}

  • Test 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());
    }
}

But when I run the test I have the following exception:

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)

Should I do any extra configuration?

Christian Frommeyer
  • 1,390
  • 1
  • 12
  • 20
Ricardo
  • 11
  • 4
  • How you providing username value and password value? – Lakshman Apr 13 '21 at 06:02
  • @Lakshman in service class, like this: @Value("${batchStatusUpdate.username}") private String username; @Value("${batchStatusUpdate.password}") private String password; – Ricardo Apr 13 '21 at 13:19
  • The error hints at a missing injection to the username field. Make sure that `application-dev.yml` is read and contains a value for `batchStatusUpdate.username`. – Christian Frommeyer Apr 14 '21 at 07:35
  • @ChristianFrommeyer That's right, but I can't understand why it doesn't inject the properties values, since when I run the project it does. – Ricardo Apr 14 '21 at 15:26

1 Answers1

1

With these modifications it worked for me:

BatchStatusClient class:

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;

In setup method:

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