V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
rainbowyao
V2EX  ›  Java

Springboot Junit 单元测试 Feign

  •  
  •   rainbowyao · 2020-06-04 16:28:21 +08:00 · 3926 次点击
    这是一个创建于 1615 天前的主题,其中的信息可能已经有所发展或是发生改变。

    使用 MockMvc 模拟前端请求,调用应用接口。接口底层是使用 Feign 调用其他服务接口。这样在单元测试的过程中,服务端的事务没有回滚?如果单元测试不回滚事务,那正常业务调用的过程中是如何保证异常后事务回滚的?

    8 条回复    2020-06-05 10:42:55 +08:00
    cweijan
        1
    cweijan  
       2020-06-04 16:43:48 +08:00
    1. 如果是出现异常, 那么就要看服务端有没有用 @Transactional 配置事务(不考虑分布式事务), 如果没有异常, 那么接口数据肯定不会回滚.
    2. 如果没有异常, mockmvc 无法回滚, @SpringBootTest 则可通过 @Transactional 回滚当前测试的操作
    3. 由于启动了 Spring 上下文, 所以这属于集成测试, 不是单元测试
    4. 最近刚写了个 Http 测试库, 底层也是用的 feign, 感兴趣可以试下, https://github.com/cweijan/http-test, 新版本即将发布.
    hantsy
        2
    hantsy  
       2020-06-04 19:27:41 +08:00
    MockMvc 仅仅是用 Mock Servlet 代替真实 Servlet 环境。你这个情况首先要 Mock 远程的接口( Feign 调用其他服务接口)。

    1 。Spring WebMvc 自带的一个 MockRestServiceServer,https://github.com/hantsy/spring-microservice-sample/blob/master/auth-service/src/test/java/com/hantsylabs/sample/springmicroservice/auth/UserServiceClientTest.java

    2 。 或者使用 http://wiremock.org/ ,有 Spring 集成。https://github.com/hantsy/spring-microservice-sample/blob/master/auth-service/src/test/java/com/hantsylabs/sample/springmicroservice/auth/UserServiceClientTest.java

    3 。Spring Cloud Contract 或者 Pact 实施 CDC ( Consumer Driven Contract )测试策略,这个在微服中测试相互调用的 Contract 是最理想。
    https://github.com/hantsy/spring-microservice-sample/blob/master/auth-service/src/test/java/com/hantsylabs/sample/springmicroservice/auth/UserServiceConsumerTest.java

    当然这个还要 Provider Side 配合,先定义 Contract,再写实现。https://github.com/hantsy/spring-microservice-sample/tree/master/contractshttps://github.com/hantsy/spring-microservice-sample/blob/master/user-service/src/test/java/com/hantsylabs/sample/springmicroservice/user/BaseTest.java

    Pact 使用一个 Docker 跑 Contract 服务器:
    https://github.com/hantsy/spring-microservice-sample/blob/master/auth-service/src/test/java/com/hantsylabs/sample/springmicroservice/auth/UserServiceConsumerPactTest.java

    https://github.com/hantsy/spring-microservice-sample/blob/master/user-service/src/test/java/com/hantsylabs/sample/springmicroservice/user/UserServiceProviderPactTest.java
    sansanhehe
        3
    sansanhehe  
       2020-06-04 21:57:25 +08:00
    接口底层是使用 Feign 调用其他服务接口。这样在单元测试的过程中,服务端的事务没有回滚?
    =====
    一般使用 @Transactional 进行集成测试的事务回滚



    如果单元测试不回滚事务,那正常业务调用的过程中是如何保证异常后事务回滚的?
    正常业务调用也有 @Transactional 注解
    limitsy
        4
    limitsy  
       2020-06-04 22:09:00 +08:00
    我的操作是 将 feign 的操作 mock 了。因为单测没必要考虑外部接口是否调用成功。
    yiyi11
        5
    yiyi11  
       2020-06-04 22:09:18 +08:00 via Android
    不是很明确你描述的问题,但我说 2 个点。
    1.springboot 单元测试,加了 @Transactional 注解,正 常 执行后,默认情况下,反 而 会回滚自动事务。我认为这个设计理念是为了重复测试。

    2.你说的服务端不会回滚事务,我认为你指的是 feign 所调用的目标服务方。这正是“分布式事务”的问题,@Transactional 只能解决自身服务的事务。
    hantsy
        6
    hantsy  
       2020-06-04 22:27:36 +08:00
    @rainbowyao

    一个基本概念,Spring 中**默认**情况下 Transaction 都是指 Local Transaction,通常指 RDBMS 中数据库事务,少量 NoSQL 支持事务的 Spring 也开始集成了,比如 Mongo 。这个事务跟 Feign 一毛关系都没有,方法用 @Transaction 包装,Feign 也不会触发回滚。
    hantsy
        7
    hantsy  
       2020-06-04 22:35:05 +08:00
    @limitsy Mock 外部调用也要 Mock 成功与各种失败的情况。

    作为 Caller,你的程序必须面临处理这些情况,而且必需知道这个外部 API 的一些细节,数据格式,http status, verbs 等。这些如果使用 Spring Cloud Contract 都是在 Contract 中定义,如,

    https://github.com/hantsy/spring-microservice-sample/tree/master/contracts/user-service-producer/src/main/resources/contracts/com/hantsylabs/sample/springmicroservice/contracts/user-service-producer/0.0.1-SNAPSHOT/auth-service/rest

    唯一不用关心是他们的具体实现。
    limitsy
        8
    limitsy  
       2020-06-05 10:42:55 +08:00
    @hantsy 对 确实需要 mock 多个返回情况,可能表述有些问题。因为楼主问的问题是 feign 的被调用方的事务回滚问题。因此我认为是应该将 feign 进行 mock,单测不与外部依赖。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1016 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 21:12 · PVG 05:12 · LAX 13:12 · JFK 16:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.