Affects: spring-boot-starter-test 2.1.6.RELEASE

Use Case: When performing an spring integration test over a get controller we add an url as a String to MockHttpServletRequestBuilder to perform such action.

Issue: When we add that url String without the protocol (for instance: "localhost:port...") the request returns a NullPointerException.

Code failing:

MockHttpServletResponse response = 
    mockMvc.perform(MockMvcRequestBuilders.get("localhost:port/some domain/etc...")).andReturn().getResponse();

Code working:

MockHttpServletResponse response = 
    mockMvc.perform(MockMvcRequestBuilders.get("http://localhost:port/some domain/etc...")).andReturn().getResponse();

Just to clarify the only difference is that the second url contains the http protcol explicitly declared

Expectation: Since http is the default protocol in many other frameworks I expect it to be inferred as url protocl if no other is defined explicitly.

Cause: Inside that MockMvcRequestBuilders.get("uri") method there is a call to a private constructor who converts that String into an actual URI

MockHttpServletRequestBuilder(HttpMethod httpMethod, String url, Object... vars) {
    this(httpMethod.name(), UriComponentsBuilder.fromUriString(url).buildAndExpand(vars).encode().toUri());
}

But it does not work properly since this.utl.getRawPath() returns null which later causes updatePathRequestProperties to throw mentioned NullPointerException Spring NullPointerException in MockHttpServletRequestBuilder for URI string with no protocol

Thanks in advance!

Comment From: rstoyanchev

MockMvcRequestBuilders uses UriComponentsBuilder.fromUriString, which can't parse the given input correctly because "localhost:" looks like a scheme.

Switching to UriComponentsBuilder.fromHttpUrl provides a more helpful error:

java.lang.IllegalArgumentException: [localhost:8080/path] is not a valid HTTP URL

I don't we should go further and fill in the protocol since we don't know if that should be "http:" or "https:" and that could lead to surprises, and possibly even possible contradictions (e.g. "localhost:443").

Comment From: rstoyanchev

Actually it looks like fromUriString is quite useful because it allows to provide a path only. We need to keep that so it comes down to, either provide a URI with a path only (i.e. no scheme, host, port), or otherwise a proper HTTP URL.

If you want shorter, why not skip the host and port too?