Spring Boot @MockBean estrange行为
这个问题与此有关。一旦发现问题,并成功应用了建议的解决方案,我将继续开发和重构代码,直到达到这一点为止。
如您在以下代码中看到的,我为我在控制器中实例化的服务类定义了一个Bean
GetExchangeRate,因此我将其直接注入控制器中,避免注入其依赖项(ExchangeRateView其实现使用的存储库JdbcTemplate)。然后,我重构了我的测试,所以我不需要模拟ExchangeRateView而是GetExchangeRate相反。但是,这样做之后我遇到了Application
failed to start错误,抱怨
com.fx.exchangerate.store.infrastructure.persistence.read.ExchangeRateJdbcView中的构造函数的参数0需要类型为’org.springframework.jdbc.core.JdbcTemplate’的bean
在我看来,尽管我嘲笑GetExchangeRate过@MockBean注释,它仍试图从应用程序上下文获得它的依赖,因为它运行正常,每当我添加@MockBean
ExchangeRateView exchangeRateView到测试类。
所以我的问题是,是否@MockBean真的这样?模拟类是否仍然需要注入其依赖项?我在这里想念什么吗?
控制器:
@RestControllerpublic class ExchangeRateStoreController {
    private AddExchangeRateRequestAdapter addExchangeRateRequestAdapter;
    private GetExchangeRate getExchangeRate;
    private CommandBus commandBus;
    @Autowired
    public ExchangeRateStoreController(CommandBus commandBus, GetExchangeRate getExchangeRate) {
        addExchangeRateRequestAdapter = new AddExchangeRateRequestAdapter();
        this.commandBus = commandBus;
        this.getExchangeRate = getExchangeRate;
    }
    @GetMapping
    public ExchangeRate get(@RequestBody GetExchangeRateRequest getExchangeRateRequest) {
        GetExchangeRateQuery query = new GetExchangeRateQuery(getExchangeRateRequest.from, getExchangeRateRequest.to, getExchangeRateRequest.date);
        return getExchangeRate.execute(query);
    }
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public void create(@RequestBody AddExchangeRateRequest addExchangeRateRequest) {
        commandBus.dispatch(addExchangeRateRequestAdapter.toCommand(addExchangeRateRequest));
    }
}
测试:
@RunWith(SpringRunner.class)@WebMvcTest(ExchangeRateStoreController.class)
public class ExchangeRateStoreControllerTest {
    @Autowired
    private MockMvc mvc;
    @MockBean
    ExchangeRateRepository exchangeRateRepository;
    @MockBean
    ExchangeRateDateValidator exchangeRateDateValidator;
    @MockBean
    GetExchangeRate getExchangeRate;
    @Test
    public void givenValidAddExchangeRateRequest_whenExecuted_thenItReturnsAnHttpCreatedResponse() 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());
    }
    @Test
    public void givenGetExchangeRateRequestThatMatchesResults_whenExecuted_thenItReturnsOkResponseWithFoundExchangeRate() throws Exception {
        when(getExchangeRate.execute(any(GetExchangeRateQuery.class))).thenReturn(anExchangeRate());
        mvc.perform(get("/")
                .content("{\"from\":\"EUR\",\"to\":\"USD\",\"date\":\"2018-11-19\"}")
                .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk());
    }
}
应用服务:
public class GetExchangeRate {    private ExchangeRateView view;
    private Clock clock;
    public GetExchangeRate(ExchangeRateView view, Clock clock) {
        this.view = view;
        this.clock = clock;
    }
    // More methods here
}
仓库实施类别:
@Repositorypublic class ExchangeRateJdbcView implements ExchangeRateView {
    JdbcTemplate jdbcTemplate;
    @Autowired
    public ExchangeRateJdbcView(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    // More methods here
}
配置类:
@Configurationpublic class ExchangeRateStoreConfig {
    @Bean
    @Autowired
    public GetExchangeRate getExchangeRate(ExchangeRateView exchangeRateView, Clock clock) {
        return new GetExchangeRate(exchangeRateView, clock);
    }
    @Bean
    public Clock clock() {
        return new Clock();
    }
    // More bean definitions
}
回答:
我终于设法找到了此问题的根本原因。我发现这是由于我@ComponentScan(basePackages =
{"com.mycompany.myapp.infrastructure", "com.mycompany.myapp.application"}
)添加了Spring Boot的主类,因此@WebMvcTest无法正常运行。
您可以在spring boot的文档中找到说明:
如果使用测试注释来测试应用程序的更特定的部分,则应避免在main方法的应用程序类上添加特定于特定区域的配置设置。
@SpringBootApplication的基础组件扫描配置定义了排除过滤器,这些过滤器用于确保切片按预期工作。如果在@SpringBootApplication注释的类上使用显式的@ComponentScan指令,请注意这些过滤器将被禁用。如果使用切片,则应再次定义它们。
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-
testing.html
以上是 Spring Boot @MockBean estrange行为 的全部内容, 来源链接: utcz.com/qa/405349.html

