Этот вопрос относится к этому .Определив проблему и успешно применив предложенное решение, я продолжил разработку и рефакторинг своего кода, пока не достиг этой точки.
Как вы можете видеть в следующем коде, я определил bean-компонент для класса обслуживания, который был создан в моем контроллере GetExchangeRate
, поэтому я внедряю его непосредственно в контроллер и избегаю внедрения его зависимостей (ExchangeRateView
репозиторий, реализация которого использует JdbcTemplate
).Затем я реорганизовал свой тест, поэтому мне не нужно высмеивать ExchangeRateView
, а GetExchangeRate
вместо этого.Однако после этого я получаю ошибку Application failed to start
, жалуясь на то, что
Параметр 0 конструктора в com.fx.exchangerate.store.infrastructure.persistence.read.ExchangeRateJdbcView требует bean-компонентанаберите 'org.springframework.jdbc.core.JdbcTemplate'
Мне кажется, что, хотя я издеваюсь от аннотации GetExchangeRate
до @MockBean
, она все еще пытается получить свои зависимости отконтекст приложения, так как он работает правильно всякий раз, когда я добавляю @MockBean ExchangeRateView exchangeRateView
в тестовый класс.
Итак, мой вопрос, действительно ли @MockBean
ведет себя так?Нужно ли вводить зависимому классу свои зависимости?Я что-то здесь упускаю?
КОНТРОЛЛЕР:
@RestController
public 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
}
КЛАСС РЕАЛИЗАЦИИ РЕАЛИЗАЦИИ:
@Repository
public class ExchangeRateJdbcView implements ExchangeRateView {
JdbcTemplate jdbcTemplate;
@Autowired
public ExchangeRateJdbcView(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// More methods here
}
КЛАСС КОНФИГУРАЦИИ:
@Configuration
public 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
}