【问题标题】:How to mock a class that been annotated with Primary如何模拟使用 Primary 注释的类
【发布时间】:2018-09-13 21:35:32
【问题描述】:

我有:

  • 一个接口:EntityService
  • 第一个实现:EntityServiceImpl - 这个类用@Primary注解
  • 另一个:EntityServiceClientImpl
  • 和具有此字段的控制器@Autowired EntityService

我想在这个控制器上做一个测试,为了这个测试是单一的,我模拟了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-boot mockito


    【解决方案1】:

    我终于找到了解决方案:spring 上下文(带有控制器、controllerAdvice 和服务模拟)而不是 spring 启动上下文

    @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。

    【讨论】:

      【解决方案2】:

      您可以稍微不同地处理它,并将@WebMvcTest@MockBean 注释结合起来,以仅使用控制器自己的最小上下文来测试控制器。

      @RunWith(SpringRunner.class)
      @WebMvcTest(controllers = EntityController.class)
      public class EntityControllerTest {
      
        @MockBean
        private EntityService entityService;
      
        @Autowired
        private MockMvc mvc;
      

      在此示例中,EntityService 将被模拟,而 MockMvc 可用于断言控制器中的请求映射。

      【讨论】:

      • 嗨,卡罗尔,这没有用 (Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test)。初始化后是否可以模拟一个bean?
      • @DamDam 您正在使用@SpringBootApplication,而这个提供@SpringBootConfiguration。您必须以一种非常不寻常的方式设置项目,它不能开箱即用。检查start.spring.io 以获得全新的干净项目设置。
      猜你喜欢
      • 2021-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多