Home > Software engineering >  How to write unit test for URI create in java
How to write unit test for URI create in java

Time:02-14

Below is the method I'm trying to write unit test using junit 5

@Value("${proxy.host}")
    private String endpoint;

public Request<Void> setAwsRequestGETParameter(String setStatusPath) {
        Request<Void> requestAws = new DefaultRequest<Void>("sts");
        requestAws.setHttpMethod(HttpMethodName.GET);
        requestAws.setEndpoint(URI.create(endpoint));
        requestAws.setResourcePath(setStatusPath);
        return requestAws;
    }

Below is the unit test I'm trying to run

@InjectMocks
    private AWSAuthHandler testAWSAuthHandler;

@Test
    public void testSetAwsRequestGETParameter() throws Exception {
        URI mockedURI = Mockito.mock(URI.class);
        assertNotNull(testAWSAuthHandler.setAwsRequestGETParameter("/status/7deaed5e-3080-45ec-89ba-403977d60c0c"));
    }

Below is the stack trace:

java.lang.NullPointerException
    at java.base/java.net.URI$Parser.parse(URI.java:3106)
    at java.base/java.net.URI.<init>(URI.java:600)
    at java.base/java.net.URI.create(URI.java:881)

Can someone please help me with the missing part? Thank you

CodePudding user response:

For setting properties of class that you can't mock you can use Spring Reflection Utils, like that:

ReflectionUtils.setField(field, target, value);

where the field is the name of the field which you want to set ("endpoint" for your case),

target is the mocked class (testAWSAuthHandler for your case)

value is the wanted value

CodePudding user response:

As Sweta Sharma said, you need to initialise AWSAuthHandler with some value for endpoint field. That's why it is better to use constructor injection rather than field one.

Assuming your AWSAuthHandler class look like this (as you didn't provide the code for the whole class):

public class AWSAuthHandler {

    @Value("${proxy.host}")
    private String endpoint;

    public Request<Void> setAwsRequestGETParameter(String setStatusPath) {
        Request<Void> requestAws = new DefaultRequest<Void>("sts");
        requestAws.setHttpMethod(HttpMethodName.GET);
        requestAws.setEndpoint(URI.create(endpoint));
        requestAws.setResourcePath(setStatusPath);
        return requestAws;
    }

You can refactor it in the following way:

public class AWSAuthHandler {

    private String endpoint;

    public AWSAuthHandler(@Value("${proxy.host}") String endpoint) {
        this.endpoint = endpoint;
    }

    public Request<Void> setAwsRequestGETParameter(String setStatusPath) {
        Request<Void> requestAws = new DefaultRequest<Void>("sts");
        requestAws.setHttpMethod(HttpMethodName.GET);
        requestAws.setEndpoint(URI.create(endpoint));
        requestAws.setResourcePath(setStatusPath);
        return requestAws;
    }

Then you can create tests for this class:

private AWSAuthHandler testAWSAuthHandler;

@BeforeEach
void setUpTests() {
    this.testAWSAuthHandler = new AWSAuthHandler("some-endpoint-here");
}

@Test
public void testSetAwsRequestGETParameter() throws Exception {
   assertNotNull(testAWSAuthHandler.setAwsRequestGETParameter("/status/7deaed5e-3080-45ec-89ba-403977d60c0c"));
}

You can read more about Spring @Value annotation here, for example: https://www.baeldung.com/spring-value-annotation

  • Related