Инъекция одного MockBean в другой - PullRequest
0 голосов
/ 23 октября 2019

У меня есть типичное SpringApplication, которое я пытаюсь проверить через MockMvc. Приложение содержит некоторые вызовы базы данных и некоторые вызовы API трехстороннего интерфейса, и я хочу имитировать их все во время тестирования сквозного потока, за исключением третьего участника

Это то, что я создал -

Контроллеркласс

public class PortfolioController {

private final PortfolioService portfolioService;
}

Класс обслуживания

public class PortfolioService {

private final PortfolioTransactionRepository portfolioTransactionRepository;
private final AlphavantageService alphavantageService;
}

AlphaVantageService

public class AlphavantageService {

private ApiConfig apiConfig;

private final RestTemplate restTemplate;

public Map<String, List<Candle>> getStockQuotes(List<String> symbols) {
    return symbols.stream().collect(Collectors.toMap(symbol -> symbol, symbol -> getQuotes(symbol)));
}
}

Теперь идет тест -

@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = PortfolioController.class)
class PortfolioControllerTest {

private List<PortfolioTransaction> transactions;

@MockBean
private AlphavantageService alphavantageService;

@MockBean
private PortfolioService portfolioService;

@Autowired
private PortfolioController portfolioController;

@Autowired
private MockMvc mockMvc;
}

Проблема в том, когдаЯ пытаюсь выполнить любой вызов mvc на сервере, AlphaVantageService не вводится внутри PortfolioService, поэтому до уровня 1 мне вводят бины, но на других уровнях я не получаю то же самое.

Это так? по дизайну или мне чего то не хватает? Как мы должны тестировать такие тесты?

1 Ответ

0 голосов
/ 23 октября 2019

На самом деле, попробовав некоторые варианты здесь и там, я нашел решение.

Также как @MockBean, у пружины также есть понятие, называемое @SpyBean. Это решило мою проблему. Так что теперь мой тест выглядит следующим образом:

@ExtendWith(SpringExtension.class)
@WebMvcTest(controllers = PortfolioController.class)
@MockBeans(value = {@MockBean(AlphavantageService.class), 
@MockBean(PortfolioTransactionRepository.class)})
@SpyBeans(value = {@SpyBean(PortfolioService.class)})
class PortfolioControllerTest {

private List<PortfolioTransaction> transactions;

@Autowired
private AlphavantageService alphavantageService;

@Autowired
@SpyBean
private PortfolioService portfolioService;

@Autowired
private PortfolioController portfolioController;

@Autowired
private MockMvc mockMvc;
}

Это работает как талисман, и я могу использовать полноценное внедрение зависимостей в тестах.

...