Spring 云服务的单元测试策略

Strategy for unit testing a Spring Cloud Service

给定以下 Spring 云设置:data-service 可以访问数据库,eureka-service 处理服务注册和发现,第三个服务 business-service将是封装业务案例的各种服务之一。

单元测试 data-service 没问题,我只是通过

关闭了 eureka
eureka.client.enabled=false

并使用内存数据库进行测试。

为了从 business-service 访问 data-service,我使用了一个名为 DataClient@FeignClient("data-service") 注释接口,在需要的地方是 @Autowired。如果两者都是 运行,则该服务被 Eureka 发现。这适用于所有服务 运行.

的类似生产的设置

但现在我想对 business-service 的某些功能进行单元测试。用

启动测试服务不会有问题
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@IntegrationTest("server.port:0")
@SpringApplicationConfiguration(classes = Application.class)

就像我在 data-service 中所做的那样。问题是我的 FeignClient 依赖于 Eureka 的发现...所以我的测试类崩溃了,因为自动装配我的 DataClient-实例不起作用。

我能否告诉 Spring 使用 DataClient 的伪造实例仅用于我的测试?还是让我的测试 运行 成为可访问的 运行 data-service 实例和我的 Eureka 服务器的唯一方法?

我的第一次尝试由于另一个错误而崩溃了...所以它可以很好地与 @Configuration 注释 class Conf 一起创建一个伪造的 DataClient 实现,例如这个:

@Bean
@Primary
public DataClient getDataClient() {
    ...
}

通过

添加到我的测试中
@SpringApplicationConfiguration(classes = {Application.class, Conf.class})

经过测试的服务实例正确使用了伪造的实现。

1、首先创建config bean,让discovery client和feignclient只在"eureka.enabled"为true

时起作用
@Configuration
@EnableDiscoveryClient
@EnableFeignClients
@ConditionalOnProperty(name = "eureka.enabled")
public class EurekaConfig {
}

2,禁用测试配置文件的eureka配置,所以在application-test.yml

eureka:
     enabled: false

3,我的项目是maven构建的,所以我为我的feign client interface创建了一个实现,例如:

@Service
public class DataServiceImpl implements DataService {}

在此之后,当您 运行 在单元测试中使用

进行测试时
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@IntegrationTest({"server.port=0", "management.port=0",    "spring.profiles.active=test"})
public abstract class AbstractIntegrationTests {}

虚假服务将注入 spring 上下文。

或者对于普通的单元测试用例,你可以只需要 mockito 模拟服务 class 并使用 set 方法或构造方法将模拟对象注入你的 class

添加云龙对单独配置注释的回答class。

如果配置 class 放置在与根包不同的包下,您需要指定 "basePackages" 以便 @EnableFeignClients 扫描带注释的 @FeignClient 组件。

com.feign.client.FeignClient.class

@FeignClient(value = "${xxxx}")
public interface FeignClient {
}

com.feign.config.EurekaConfig.class

@Configuration
@EnableFeignClients(basePackages = {"com.feign.client"})
@EnableEurekaClient
@ConditionalOnProperty(name = "eureka.enabled")
public class EurekaClientConfig {
}

Ps。我无法对原始回复发表评论,所以我创建了一个新答案。