本文介紹了使用Spring WebFlux和WebTestClient獲取請求屬性的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
使用Spring WebFlux時,我無法將我正在設置的屬性從WebTestClient
綁定到RestController
。
我試了我能想到的兩種方法。
首先使用@RequestAttribute
注釋,我得到:
無法處理請求[Get/Attributes/Annotation]:響應狀態為400,原因為”缺少字符串類型的請求屬性‘ATTRIBUTE’”
然后我嘗試使用ServerWebExchange,結果null
。
這是我的控制器:
@RestController
@RequestMapping("/attributes")
public class MyController {
@GetMapping("/annotation")
public Mono<String> getUsingAnnotation(@RequestAttribute("attribute") String attribute) {
return Mono.just(attribute);
}
@GetMapping("/exchange")
public Mono<String> getUsingExchange(ServerWebExchange exchange) {
return Mono.just(exchange.getRequiredAttribute("attribute"));
}
}
這是我的失敗測試:
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyControllerTest {
@Autowired
ApplicationContext context;
WebTestClient webClient;
@Before
public void setup() {
webClient = WebTestClient.bindToApplicationContext(context)
.configureClient()
.build();
}
@Test
public void testGetAttributeUsingAnnotation() {
webClient.get()
.uri("/attributes/annotation")
.attribute("attribute", "value")
.exchange()
.expectStatus()
.isOk();
}
@Test
public void testGetAttributeUsingExchange() {
webClient.get()
.uri("/attributes/exchange")
.attribute("attribute", "value")
.exchange()
.expectStatus()
.isOk();
}
}
在我的實際應用程序中,我有一個SecurityConextRepository,它從(解碼的)標頭值設置一些屬性,我想要獲取這些屬性。
推薦答案
我在一個測試中遇到了同樣的問題,該測試以前使用MockMvc,后來不得不轉換為使用WebClient。像@jcfandino一樣,我希望WebClient上的.attribute()
方法的工作方式類似于MockMvc的requestAttribute()
。
我還沒有發現.attribute()
應該如何使用,但我已經通過添加自定義測試篩選器繞過了整個問題。我不確定此方法是否正確,但由于此問題尚未回答,下面的方法可能對遇到相同問題的人有幫助。
@WebFluxTest(controllers = SomeController.class)
@ComponentScan({ "com.path1", "com.path2" })
class SomeControllerTest {
// define a test filter emulating the server's filter (assuming there is one)
private class AttributeFilter implements WebFilter {
String attributeValue;
public AttributeFilter(String filterAttributeValue) {
attributeValue = filterAttributeValue;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
// add the desired attributes
exchange.getAttributes().put(SomeController.ATTR_NAME, attributeValue);
return chain.filter(exchange);
}
}
// mock the service the controller is dependend on
@MockBean
AppService appService;
// define the test where the controller handles a get() operation
@Test
void testMethod() {
// mock the app service
when(appService.executeService(anyString(), anyString())).thenAnswer(input -> {
// ... return some dummy appData
});
var testClient= WebTestClient.bindToController(new SomeController(appService))
.webFilter(new SomeControllerTest.AttributeFilter("someValue"))
.build();
try {
var response = testClient
.get()
.uri("someroute")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBody(AppData.class);
} catch (Exception e) {
fail("exception caught in testMethod", e);
}
}
}
這篇關于使用Spring WebFlux和WebTestClient獲取請求屬性的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,