Springboot Junit 单元测试 Feign

2020-06-04 16:28:21 +08:00
 rainbowyao

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

3972 次点击
所在节点    Java
8 条回复
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
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
2020-06-04 21:57:25 +08:00
接口底层是使用 Feign 调用其他服务接口。这样在单元测试的过程中,服务端的事务没有回滚?
=====
一般使用 @Transactional 进行集成测试的事务回滚



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

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

一个基本概念,Spring 中**默认**情况下 Transaction 都是指 Local Transaction,通常指 RDBMS 中数据库事务,少量 NoSQL 支持事务的 Spring 也开始集成了,比如 Mongo 。这个事务跟 Feign 一毛关系都没有,方法用 @Transaction 包装,Feign 也不会触发回滚。
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
2020-06-05 10:42:55 +08:00
@hantsy 对 确实需要 mock 多个返回情况,可能表述有些问题。因为楼主问的问题是 feign 的被调用方的事务回滚问题。因此我认为是应该将 feign 进行 mock,单测不与外部依赖。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/678631

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX