将一个 MockBean 注入另一个 MockBean
Injecting one MockBean into another
我有一个典型的 SpringApplication,我正在尝试通过 MockMvc 对其进行测试。该应用程序包含一些数据库调用和一些第三方 api 调用,我想模拟所有这些调用,同时测试端到端流程,第三方
除外
这是我创建的 -
控制器class
public class PortfolioController {
private final PortfolioService portfolioService;
}
服务Class
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 级,我得到了 bean 注入,但在更深层次上,我不明白。
是设计使然还是我遗漏了什么?我们应该如何测试这样的测试用例?
实际上,在尝试了一些选项之后,我找到了解决方案。
就像@MockBean
一样,spring也有一个概念叫做@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;
}
这很有用,我可以在测试中使用完整的依赖注入。
我有一个典型的 SpringApplication,我正在尝试通过 MockMvc 对其进行测试。该应用程序包含一些数据库调用和一些第三方 api 调用,我想模拟所有这些调用,同时测试端到端流程,第三方
除外这是我创建的 -
控制器class
public class PortfolioController {
private final PortfolioService portfolioService;
}
服务Class
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 级,我得到了 bean 注入,但在更深层次上,我不明白。
是设计使然还是我遗漏了什么?我们应该如何测试这样的测试用例?
实际上,在尝试了一些选项之后,我找到了解决方案。
就像@MockBean
一样,spring也有一个概念叫做@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;
}
这很有用,我可以在测试中使用完整的依赖注入。