Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance MockMvcWebTestClient to allow applying RequestPostProcessors #30233

Closed

Conversation

justin-tay
Copy link
Contributor

Potentially fixes related issues like spring-projects/spring-security#9257 and spring-projects/spring-security#11334

This PR is unpolished and is just to illustrate the idea of allowing mutateWith on MockMvc RequestPostProcessors as I'm not even sure if this design approach would be acceptable.

The basic design idea is to have the MockMvcWebTestClient interface extend WebTestClient with some MockMvc specific methods.

package com.example;

import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.oidcLogin;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.client.MockMvcWebTestClient;
import org.springframework.web.context.WebApplicationContext;

@SpringBootTest
@AutoConfigureMockMvc
@TestInstance(Lifecycle.PER_CLASS)
@ActiveProfiles("test")
class MockMvcTest {
	MockMvcWebTestClient client;

	@Autowired
	void setupClient(WebApplicationContext context) {
		client = MockMvcWebTestClient.bindToApplicationContext(context).apply(springSecurity()).build();
	}
	
	@Test
	void givenOidcLoginShouldReturnOk() {
		client.mutateWith(oidcLogin()).get().uri("/login-user").exchange().expectStatus()
				.isOk();
	}
}

@pivotal-cla
Copy link

@justin-tay Please sign the Contributor License Agreement!

Click here to manually synchronize the status of this Pull Request.

See the FAQ for frequently asked questions.

@pivotal-cla
Copy link

@justin-tay Thank you for signing the Contributor License Agreement!

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Mar 30, 2023
@rstoyanchev rstoyanchev added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Apr 17, 2023
Copy link
Contributor

@rstoyanchev rstoyanchev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@justin-tay thanks for experimenting with this.

WebTestClient is a two-phase builder, first to build the server and then the test client. This creates a single chained flow, but once you've moved to the second phase, there is no way to return to the server phase. mutate() only drops you in the builder for the second phase. The same is true for MockMvcWebTestClient which builds a MockMvc server in phase 1 and transitions to the test client builder.

So for MockMvcWebMvcTest client to introduce a mutate() with a Builder that extends the WebTestClient.Builder is essentially adding server builder methods as a subclass of client builder methods. I don't think this is in the right direction, and it would also be difficult to accommodate the same for all the other WebTestClient server builder choices with a single mutate().

The other mutate with a WebTestClientConfigurer is what provides an option to modify the server. Here we pass the ClientHttpConnector and that could be one possible direction, but we would need to enhance MockMvcHttpConnector to allow mutation, e.g. to add RequestPostProcessors. From a quick look there is also a WiretapConnector wrapper around the actual ClientHttpConnector in use that we may have to unwrap when applying a WebTestClientConfigurer.

Would you like to redo your pull request? If not I can also make some changes along those lines.

transitioned to building the test client, there is no return to the built, mutate() can change the test client. longer be changed

@justin-tay
Copy link
Contributor Author

I see your point about the design. I tried to pick this up again but I don't really know how to do this without making breaking changes, plus I think my initial design was pretty off track. I think it might be best for you to make the changes instead.

@justin-tay justin-tay closed this Sep 21, 2023
@rstoyanchev
Copy link
Contributor

Thanks @justin-tay for inserting some momentum into this. I've created #31298.

@rstoyanchev rstoyanchev added status: superseded An issue that has been superseded by another and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Sep 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: superseded An issue that has been superseded by another
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants