SpringBoot @WebMvcTest和@MockBean无法正常工作

时间:2018-11-28 17:16:14

标签: java spring unit-testing spring-mvc spring-boot

似乎@WebMvcTest@MockBean无法正常工作。也许我丢失了一些东西……我有一个带有一些依赖关系的控制器,正在使用@MockBean进行模拟,但是该应用程序无法启动,因为它找不到在这种情况下我不需要的另一个bean。

控制器:

@RestController
public class ExchangeRateStoreController {
    private AddExchangeRate addExchangeRate;
    private AddExchangeRateRequestAdapter addExchangeRateRequestAdapter;
    private GetExchangeRate getExchangeRate;
    private GetExchangeRateRequestAdapter getExchangeRateRequestAdapter;

    @Autowired
    public ExchangeRateStoreController(ExchangeRateRepository exchangeRateRepository, ExchangeRateDateValidator exchangeRateDateValidator, ExchangeRateView exchangeRateView) {
        addExchangeRate = new AddExchangeRate(exchangeRateRepository, exchangeRateDateValidator);
        addExchangeRateRequestAdapter = new AddExchangeRateRequestAdapter();
        getExchangeRate = new GetExchangeRate(exchangeRateView);
        getExchangeRateRequestAdapter = new GetExchangeRateRequestAdapter();
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public void create(@RequestBody AddExchangeRateRequest addExchangeRateRequest) {
        addExchangeRate.execute(addExchangeRateRequestAdapter.toCommand(addExchangeRateRequest));
    }
}

测试:

@RunWith(SpringRunner.class)
@WebMvcTest(ExchangeRateStoreController.class)
public class ExchangeRateStoreControllerTest {

    @Autowired
    private MockMvc mvc;  
    @MockBean
    ExchangeRateRepository exchangeRateRepository;
    @MockBean
    ExchangeRateDateValidator exchangeRateDateValidator;
    @MockBean
    ExchangeRateView exchangeRateView;

    @Test
    public void givenValidExchangeRateCommand_whenCreate_thenOK() throws Exception {
        String validRequestBody = "{\"from\":\"EUR\",\"to\":\"USD\",\"amount\":1.2345,\"date\":\"2018-11-19\"}";

        doNothing().when(exchangeRateDateValidator).validate(any());
        doNothing().when(exchangeRateRepository).save(any());

        mvc.perform(post("/").content(validRequestBody).contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isCreated());
    }

应用:

@SpringBootApplication
@EnableJpaRepositories("com...exchangerate.store.infrastructure.persistence")
@EntityScan("com...exchangerate.store.infrastructure.persistence")
@ComponentScan(basePackages = {"com...exchangerate.store.infrastructure", "com...exchangerate.store.application"} )
public class ExchangeRateStoreApplication {
    public static void main(String[] args) {
        SpringApplication.run(ExchangeRateStoreApplication.class, args);
    }
}

以及运行测试时出现的错误:

  

申请无法开始

     
     

说明:

     

一个组件需要一个名为“ entityManagerFactory”的bean,该bean可以   找不到。

     

操作:

     

考虑在您的计算机中定义一个名为“ entityManagerFactory”的bean   配置。

但是,正如您所看到的,entityManagerFactory不是控制器的依赖项。那么,为什么测试试图加载该bean?我正在嘲笑所有的控制器依赖关系,所以我认为它不应该这样做。

2 个答案:

答案 0 :(得分:2)

问题是由您在应用程序的主类上使用@EnableJpaRepositories引起的。通过将其放在主类上,表示无论您要测试哪个特定功能,都必须始终启用JPA存储库。

您可以通过以下方法之一解决问题:

  • @EnableJpaRepositores@EntityScan移动到单独的JPA特定的配置类上
  • 删除@EnableJpaRepositories@EntityScan并依靠自动配置的默认值。为此,您的存储库和实体必须位于主类包的子包中。

Spring Boot的reference documentation中有关于此的更多信息,其中显示以下内容:

  

如果您使用测试注释来测试应用程序的特定部分,则应避免在主方法的应用程序类中添加特定于特定区域的配置设置。

在这种情况下,特定于特定区域的配置设置为@EnableJpaRepositories

答案 1 :(得分:0)

你好,这篇文章有一个很好的链接:EntityManagerFactory not found in SpringBoot

您可以检查您的spring boot jpa集成,并有一些很好的技巧来设置您的环境。