Home > Enterprise >  Prevent to use @Configuration/@ConfigurationProperties in testing using Spock, Groovy
Prevent to use @Configuration/@ConfigurationProperties in testing using Spock, Groovy

Time:09-14

I have this Class Configuration (currently I can't to read the .yml file)

@Data
@Configuration
@ConfigurationProperties(prefix = "clients.my-microservice-client")
public class MyMicroserviceClientConfiguration {

    @NotBlank
    private String urlBinaryAttachment;

}

I have a Client that will use the previous configuration.

public class MyMicroserviceClientImpl implements MyMicroserviceClient {

    private final MyMicroserviceClientConfiguration myMicroserviceClientConfiguration;
    private final RestTemplate restTemplate;

    @Override
    public byte[] getBinaryDoc(String idContent) {
        Map<String, String> uriVars = new HashMap<>();
        uriVars.put("idContent", idContent);

        UriComponents builder = UriComponentsBuilder
                .fromHttpUrl(myMicroserviceClientConfiguration.getUrlBinaryAttachment())  // LINE 48 of MyMicroserviceClientImpl.java
                .buildAndExpand(uriVars);

        ResponseEntity<byte[]> response = restTemplate.getForEntity(builder.toUriString(),
                byte[].class);

        return response.getBody();
    }
}

Now, I try to test the getBinaryDoc method.

def "getBinaryDoc"() {
    given: "calling getBinaryDoc"
    ResponseEntity<byte[]> response = new ResponseEntity<byte[]>("bytes".bytes, HttpStatus.OK)
    def uriVars = new HashMap<>();
    uriVars.put("idContent", "idContent");

    def url = "http://localhost:8080"

    UriComponentsBuilder.fromHttpUrl(url) .buildAndExpand(uriVariables) >> {}

    restTemplate.getForEntity(url, byte[].class) >> response

    when: "calling method of my service"
    byte[] responseBytes = myMicroserviceClient.getBinaryDoc(url)  // LINE 75 of MyMicroserviceClientSpec.groovy

    then: "Checking bytes length"
    responseBytes.length == "bytes".bytes.length
}

When I run my test, I get:

HTTP URL must not be null
java.lang.IllegalArgumentException: HTTP URL must not be null
    at org.springframework.util.Assert.notNull(Assert.java:134)
    at org.springframework.web.util.UriComponentsBuilder.fromHttpUrl(UriComponentsBuilder.java:250)
    at my.package.client.mymicroserviceclient.MyMicroserviceClientImpl.getBinaryDoc(MyMicroserviceClientImpl.java:48)
    at my.package.client.mymicroserviceclient.MyMicroserviceClientSpec.getBinaryDoc(MyMicroserviceClientSpec.groovy:75)

The Configuration .yml file still is not deployed in the proper environment!

Is it possible to prevent that the implementation of my client get value of configuration on the line 48?

How to skip that code line?

CodePudding user response:

You can't skip that line, don't fight against the Spring Framework. The correct way to test this is to inject a MyMicroserviceClientConfiguration with a valid value.

The easiest way is to use

  1. @TestPropertySource(properties=['clients.my-microservice-client.url-binary-attachment=http://localhost/validUrl']) or use
  2. @SpringBootTest(properties=['clients.my-microservice-client.url-binary-attachment=http://localhost/validUrl']) directly.

You can use MockServer or WireMock if you need to have a fake web server.

CodePudding user response:

Try this

In your Specification file.

class MyMicroserviceClientSpec extends Specification {
    private MyMicroserviceClientConfiguration myMicroserviceClientConfiguration

    void setup() {
        myMicroserviceClientConfiguration = Mock(MyMicroserviceClientConfiguration)
    }

    def "getBinaryDoc"() {

        given: "your comment"
        ... // some needed code

        myMicroserviceClientConfiguration.urlBinaryAttachment >> "yourURL"
        ... // some needed code

        when: "calling method of my service"
        byte[] responseBytes = myMicroserviceClient.getBinaryDoc(url)
        ... // some needed code

        then:
        ... // some needed code
    }
}
  • Related