在使用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();
}
}
在我的实际应用程序中,我有一个SecurityContextRepository,它从(解码的)头文件值中设置一些属性,我想要获取这些属性。
发布于 2018-07-25 04:37:36
在服务器端和客户端,请求属性都应该被视为类似于Map的数据结构,可用于在客户端/服务器中传输信息(用于过滤器、编解码器等)。
该信息不会通过网络发送。
如果要将信息从客户端发送到服务器,则应该查看请求参数或请求正文本身。
发布于 2021-11-11 09:19:12
我在一个测试中遇到了同样的问题,该测试以前使用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);
}
}
}
https://stackoverflow.com/questions/51503196
复制相似问题