使用@WebFluxTest测试RouterFunction

时间:2018-02-17 15:01:44

标签: spring spring-boot testing spock spring-webflux

我有一个路由器功能,我想使用spock进行测试。看起来像这样

@Configuration
public class WebConfig {

    /**
     * Router function.
     * @return string
     */
    @Bean
    public RouterFunction<?> helloRoute() {
        return route(GET("/judge/router/hello"),
                request -> ServerResponse.ok().body(fromPublisher(Mono.just("Hello Router WebFlux"), String.class)));
    }

}

它的测试看起来像这样

@WebFluxTest
class JudgeRuleEngineMvcTestSpec extends Specification {

    @Autowired
    WebTestClient webClient;

    def "router function returns hello"() {
        expect:
            webClient.get().uri("/judge/router/hello")
                .exchange()
                .expectStatus().isOk()
                .expectBody(String.class)
                .isEqualTo("Hello WebFlux") // should fail
    }
}

但它失败了,因为它返回200而不是404状态。它似乎无法找到REST本身。

我还使用RestController对基本GetMapping进行了测试,效果很好。

@RestController
@RequestMapping("/judge/rest")
public class BasicController {
    private static final Logger LOGGER = LoggerFactory.getLogger(BasicController.class);

    @GetMapping("/hello")
    public Mono<String> handle() {
        LOGGER.debug("Invoking hello controller");
        return Mono.just("Hello WebFlux");
    }

}

def "mvc mono returns hello"() {
    expect:
        webClient.get().uri("/judge/rest/hello")
            .exchange()
            .expectStatus().isOk()
            .expectBody(String.class)
                .isEqualTo("Hello WebFlux")
}

为什么它失败了路由器功能?

2 个答案:

答案 0 :(得分:2)

这是@WebFluxTest的已知限制 - 目前没有一致的方法来检测RouterFunction bean,就像我们对@Controller类一样。

请参阅this Spring Boot issue for future reference

答案 1 :(得分:0)

要添加到Brian's answer中,kizux在他发布的Github问题链接中似乎提到了一种解决方法

您可以使用bindToApplicationContext通过WebTestClient测试路由器功能

报价

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {RouteConfiguration.class, UserHandler.class})
@WebFluxTest
public class UserHandlerTest
{
    @Autowired
    private ApplicationContext context;
    @MockBean(name="userService")
    private UserService userService;
    private WebTestClient testClient;

    @Before
    public void setUp()
    {
        testClient = WebTestClient.bindToApplicationContext(context).build();
    }

    ...