Spring 如何让aspectj在webtestclient中工作?

Spring 如何让aspectj在webtestclient中工作?,spring,aspectj,spock,spring-webflux,Spring,Aspectj,Spock,Spring Webflux,我有一些由SpringWebFlux实现的API。现在我需要写一些UT来测试它。我用spock编写UT代码,并用WebTestClient.bindToRouterFunction方法创建一个模拟服务器。它也起了作用。但是我发现我有一个ParaCheckAspect来检查api的参数,它不起作用,因为我没有创建SpringIOC。我必须查看WebTestClient api,它没有任何api来注册我的ParaCheckAspect。请告诉我你是否知道解决这个问题的方法 我已经看过spring文档

我有一些由SpringWebFlux实现的API。现在我需要写一些UT来测试它。我用spock编写UT代码,并用WebTestClient.bindToRouterFunction方法创建一个模拟服务器。它也起了作用。但是我发现我有一个ParaCheckAspect来检查api的参数,它不起作用,因为我没有创建SpringIOC。我必须查看WebTestClient api,它没有任何api来注册我的ParaCheckAspect。请告诉我你是否知道解决这个问题的方法

我已经看过spring文档了。它没有这方面的有效信息

/**
*检查参数是否有效
*/
@面貌
@Slf4j
@组成部分
公共类副检查方面{
@大约(“execution(*com.winston.springboot.handler.*(…)”)
公共对象验证(ProceedingJoinPoint点)抛出可丢弃的{
for(int i=0;iMono.error(新的ResponseStatusException(HttpStatus.BAD_请求,e.getMessage()));
}else if(point.getArgs()[i]通量实例){
point.getArgs()[i]=((通量)point.getArgs()[i])
.doOnNext(此::检查)
.onErrorResume(e->Mono.error(新的ResponseStatusException(HttpStatus.BAD_请求,e.getMessage()));
}
}
返回点。继续(point.getArgs());
}
专用无效检查(对象obj){
//一些验证程序代码
}
}
这还不是一个答案,目前只是与OP沟通的一种方式,因为我需要空间来发布代码和调用堆栈,这在评论中是不可能的

免责声明:我从未使用过Gradle(只有Maven),对Webflux一无所知。但有几件事我可以说:

  • 克隆您的项目时,我注意到的第一件事是您忘记了build.gradle中的
    apply plugin:“groovy”
    。没有它,您的Spock测试甚至无法编译和运行
  • 添加Groovy插件后,运行测试将产生以下执行选项:
方法org.springframework.test.web.reactive.server.WebTestClient.bindToRouterFunction(Lorg/springframework/web/reactive/function/server/RouterFunction;)Lorg/springframework/test/web/reactive/server/
java.lang.CompatibileClassChangeError:Method org.springframework.test.web.reactive.server.WebTestClient.bindToRouterFunction(Lorg/springframework/web/reactive/function/server/RouterFunction;)Lorg/springframework/test/web/reactive/server/
位于com.winston.webflux.UserHandlerSpec.setup(UserHandlerSpec.groovy:25)
com.winston.webflux.UserHandlerSpec>测试用户保存失败
UserHandlerSpec.groovy上的java.lang.CompatibileClassChangeError:25
这是你的问题吗?您从未说过您实际遇到了什么问题,只是“AspectJ”(您真正的意思是SpringAOP)在您的测试中不起作用


还有一个示例应用程序。我可以启动它,但我需要做什么才能使方面生效?对不起,我真的不是一个春天的家伙,我只是一种AOP专家和了解斯波克,太。所以请先帮我理解这个问题。如果在浏览器中打开,我只会看到一个“白标错误页面”,控制台上没有任何日志输出。

如果您使用spring,您应该包括
spock-spring
模块,这会将spring支持添加到
规范中。然后您需要使用
@springbootest
或类似的spring注释,例如
@WebFluxTest
,并注入处理程序。这就是spring创建实例并应用AOP拦截器的方法。

您为什么混合使用spring、Spock和Mockito的三种不同测试工具,以及为什么您不只是以Spock的方式创建模拟或存根,而不是使其复杂化并让Mockito注入它们?另外,如果在
setup()
中对每个特性方法进行了初始化,为什么测试客户机是一个
@Shared
变量?此外,示例代码使用了这里没有显示的几个类的导入,因此没有人可以编译和运行您的测试来重现您的问题。也许你想提供一个,可能是在GitHub中。SpringAOP是一个阻塞,不能用于将东西“强制”到Flux和monos,希望它能与SpringWebFlux一起工作。你的代码都不起作用,因为没有人订阅你的任何流量。如果不知道自己在做什么,就不能将Spring AOP与webflux一起使用。所以你应该用另一种方式进行检查。@kriegaex谢谢你的建议。我已将代码推送到GitHub。链接是:。@ThomasAndolf谢谢你的关注。spring AOP在webflux中运行良好。但我不知道如何在UT代码中使用它。因为我不喜欢api在UT.ofc中调用它,它工作得很好,因为您正在进行一些难看的转换,并返回一个
对象
,有很多更好的方法进行验证检查,然后使用AspectsThank非常感谢您的帮助。这是我第一次在stackoverflow上提问。而且我的母语不是英语,所以我可能还没有清楚地描述这个问题。再次感谢你的耐心。此应用程序提供了一个仅支持http post请求的api。URL:。参数:{“name”:“tony”,“age”:21}我通过邮递员测试此api。问题是,当我通过邮递员调用此api时,将调用ParaCheckAspect并在控制台上打印“ParaCheckAspect.check已调用”。现在我在UT代码中通过WebTestClient调用这个api,ParacheAspect没有调用。我还没有找到注册ParacheAspect的api。我不知道这是否澄清了我的问题。如果我运行这个应用程序,我可以使用
curl-s-X POST-d'{“name”:“tony”,“age”:21}'-H“Content Type:application/json”http://localhost:8080/user/
,获取有效结果并查看

import com.winston.springboot.config.routers.UserRouter
import com.winston.springboot.entity.User
import com.winston.springboot.handler.UserHandler
import org.mockito.InjectMocks
import org.mockito.MockitoAnnotations
import org.springframework.test.web.reactive.server.WebTestClient
import org.springframework.web.reactive.function.BodyInserters
import spock.lang.Shared
import spock.lang.Specification

class UserHandlerSpec extends Specification {

    @Shared
    WebTestClient testClient

    @InjectMocks
    UserHandler userHandler

    void setup() {
        MockitoAnnotations.initMocks(this)
        def function = routeFunction()
        def routeFunctionSpec = WebTestClient.bindToRouterFunction(function)
        testClient = routeFunctionSpec
                .configureClient()
                .baseUrl("http://127.0.0.1:8089")
                .build()
    }

    def 'test userSave'() {
        given:
        User user = User.builder().name("lina").age(10).build()
        when:
        testClient.post().uri("/user")
                .body(BodyInserters.fromObject(user))
                .exchange()
                .expectStatus()
                .isOk()
                .expectBody(User.class)
                .returnResult();
        then:
        noExceptionThrown();
    }

    def routeFunction() {
      return  new UserRouter().userRouterFunction(userHandler);
    }

}