我有:
- 接口(interface):
EntityService
- 第一个实现:
EntityServiceImpl
- 这个类用@Primary
注释 - 另一个:
EntityServiceClientImpl
- 和一个具有此字段的 Controller
@Autowired EntityService
我想在这个 Controller 上做一个测试,为了让这个测试是单一的,我模拟了 EntityService
。
所以这段代码当然不起作用,因为 Spring 检测到两个用 Primary 注释的 bean:
@Configuration
class EntityControllerTestConfig {
@Bean
@Primary
EntityService entityService() {
return mock(EntityService.class);
}
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestApplication.class)
@WebAppConfiguration
@ContextConfiguration(classes = EntityControllerTestConfig.class)
public class EntityControllerTest {
@Autowired
private EntityService entityService;
...
@SpringBootApplication(scanBasePackages= "com.company.app")
@EntityScan (basePackages = {"com.company.app" }, basePackageClasses = {Jsr310JpaConverters.class })
@EnableJpaRepositories("com.company.app")
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
我试图找到另一种方法来模拟和排除测试配置中的 EntityServiceClient
但我无法模拟。 (参见:exclude @Component from @ComponentScan)
最佳答案
我最终找到了解决方案:一个 spring 上下文(带有 Controller 、controllerAdvice 和服务模拟)而不是 spring boot 上下文
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class EntityControllerTest {
@Configuration
public static class EntityControllerTestConfig {
@Bean
public EntityService entityService() {
return mock(EntityService.class);
}
@Bean
public EntityController entityController() {
return new EntityController(entityService());
}
}
@Autowired
private EntityService entityService;
@Autowired
private EntityController entityController;
private MockMvc mockMvc;
@Before
public void setup() throws DomaineException {
this.mockMvc = MockMvcBuilders
.standaloneSetup(entityController)
.setControllerAdvice(new myControllerAdvice())
.build();
注意:从 Spring 4.2 开始,您可以像这样设置 ControllerAdvice。
关于spring-boot - 如何模拟一个用 Primary 注释的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49649044/