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。我无法对原始回复发表评论,所以我创建了一个新答案。
给定以下 Spring 云设置:data-service
可以访问数据库,eureka-service
处理服务注册和发现,第三个服务 business-service
将是封装业务案例的各种服务之一。
单元测试 data-service
没问题,我只是通过
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。我无法对原始回复发表评论,所以我创建了一个新答案。