question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

MockMvc tests that use `contextPath` fail with Thymeleaf 3.1

See original GitHub issue

While preparing an application to use the upcoming Spring Boot v3 a lot of tests fail where MockMvc is used. The application is configured with a server.servlet.context-path which is also used in the tests. For Spring Boot v2 these tests are successfully running. The minimal test is:

@SpringBootTest
@AutoConfigureMockMvc
class DemoApplicationTests {

    @Autowired
    private MockMvc mockMvc;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    @Test
    public void shouldServeIndex_mockMvc() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get(contextPath + "/").contextPath(contextPath))
                .andExpect(status().isOk());
    }

    @Test
    public void shouldServeIndex_webClient() throws Exception {
        try (final var webClient = MockMvcWebClientBuilder.mockMvcSetup(mockMvc).contextPath(contextPath).build()) {
            webClient.getPage("http://localhost" + contextPath + "/");
        }
    }

}

Running with Spring Boot 3.0.0-RC2 both tests fail with:

[ERROR] shouldServeIndex_mockMvc  Time elapsed: 0.236 s  <<< ERROR!
jakarta.servlet.ServletException: Request processing failed: java.lang.IllegalArgumentException: Cannot build an application for a request which servlet context does not match with the application that it is being built for.
        at com.example.demo.DemoApplicationTests.shouldServeIndex_mockMvc(DemoApplicationTests.java:26)
Caused by: java.lang.IllegalArgumentException: Cannot build an application for a request which servlet context does not match with the application that it is being built for.
        at com.example.demo.DemoApplicationTests.shouldServeIndex_mockMvc(DemoApplicationTests.java:26)

The check in org.thymeleaf.web.servlet.JakartaServletWebApplication#servletContextMatches fails because the provided current context path is not equal (it’s empty) to the requested one. The module for Spring (Framework) 5 does not check the context paths.

A test project can be found here.

Issue Analytics

  • State:open
  • Created 10 months ago
  • Reactions:1
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
agebhar1commented, Dec 2, 2022

@philwebb thank you for discussing this issue. It will work for me to remove the context path from the Tomcat configuration and add them to all controller. I’d like the test URLs to be equal to the productive ones. Maybe a hint should be added to the documentation to be aware of the situation.

1reaction
philwebbcommented, Nov 14, 2022

I’m a little worried that if we try and set the context path in the tests then it might break a lot of users in the other direction.

The javadoc for MockHttpServletRequestBuilder.contextPath(...) states:

In most cases, tests can be written by omitting the context path from the requestURI. This is because most applications don’t actually depend on the name under which they’re deployed. If specified here, the context path must start with a “/” and must not end with a “/”.

If we set the context path on our mock servlet then all mock MVC calls will need to remember to also set it.

If I drop it entirely from the tests, things work:

@SpringBootTest
@AutoConfigureMockMvc
class DemoApplicationTests {

	@Autowired
	private MockMvc mockMvc;

	@Test
	public void shouldServeIndex_mockMvc() throws Exception {
		mockMvc.perform(MockMvcRequestBuilders.get("/")).andExpect(status().isOk());
	}

	@Test
	public void shouldServeIndex_webClient() throws Exception {
		try (final var webClient = MockMvcWebClientBuilder.mockMvcSetup(mockMvc).build()) {
			webClient.getPage("http://localhost/");
		}
	}

}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Testing - Spring
Spring TestContext Framework. WebTestClient. MockMvc. Testing Client Applications. Annotations. 3.1. Goals of Integration Testing.
Read more >
Spring REST mock context path - java - Stack Overflow
2 Answers 2 · 4. Your (src/main) code can set the context path using property server.servlet.context-path . It's disappointing that your (src/test) code...
Read more >
correct context path handling-Spring MVC - appsloveworld
If you are using Thymeleaf, you should be able to use <a th:href="@{/about}">Link</a> assuming that <html xmlns:th="http://www.thymeleaf.org"> has been ...
Read more >
14. Integration Testing - Developer's Documentation Collections
The TestContext framework is agnostic of the actual testing framework in use, thus allowing instrumentation of tests in various environments including JUnit ...
Read more >
Deploy a Jakarta EE application to the root context - rieckpil
You can use the root context / for your Jakarta EE application. ... route to / instead of remembering the actual context path...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found