SpringBoot @WebMvcTest 和 @MockBean 未按预期工作

2023-12-21

看起来@WebMvcTest and @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));
    }
}

TEST:

@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,它可以 找不到。

Action:

考虑在您的项目中定义一个名为“entityManagerFactory”的 bean 配置。

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


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

您可以通过执行以下操作之一来解决您的问题:

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

Spring Boot 中有更多关于此的信息参考文档 https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-testing-spring-boot-applications-detecting-config其中写着以下内容:

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot @WebMvcTest 和 @MockBean 未按预期工作 的相关文章

随机推荐