java 单元测试中的 Spring Boot 数据源
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49559185/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Boot Datasource in unit tests
提问by Evgeni Dimitrov
I have a simple Spring Boot web app, that reads from a database and return a JSON response. I have the following test configuration:
我有一个简单的 Spring Boot Web 应用程序,它从数据库中读取数据并返回一个 JSON 响应。我有以下测试配置:
@RunWith(SpringRunner.class)
@SpringBootTest(classes=MyApplication.class, properties={"spring.config.name=myapp"})
@AutoConfigureMockMvc
public class ControllerTests {
@Autowired
private MockMvc mvc;
@MockBean
private ProductRepository productRepo;
@MockBean
private MonitorRepository monitorRepo;
@Before
public void setupMock() {
Mockito.when(productRepo.findProducts(anyString(), anyString()))
.thenReturn(Arrays.asList(dummyProduct()));
}
@Test
public void expectBadRequestWhenNoParamters() throws Exception {
mvc.perform(get("/products"))
.andExpect(status().is(400))
.andExpect(jsonPath("$.advice.status", is("ERROR")));
}
//other tests
}
I have a DataSource bean that is configured in the main configuration of the application. When I run the tests Spring tries to load the context and fails, because the datasource is taken from JNDI. In general I want to avoid creating a datasource for this tests, because I have the repositories mocked.
我有一个在应用程序的主配置中配置的 DataSource bean。当我运行测试时,Spring 尝试加载上下文并失败,因为数据源来自 JNDI。一般来说,我想避免为此测试创建数据源,因为我模拟了存储库。
Is it possible to skip the creation of datasource when running the unit tests?
运行单元测试时是否可以跳过数据源的创建?
In memory database for testing is not an option, because my database creation script has a specific structure and cannot be easily executed from classpath:schema.sql
用于测试的内存数据库不是一种选择,因为我的数据库创建脚本具有特定的结构并且无法从 classpath:schema.sql 轻松执行
EditThe datasource is defined in MyApplication.class
编辑数据源定义在MyApplication.class
@Bean
DataSource dataSource(DatabaseProeprties databaseProps) throws NamingException {
DataSource dataSource = null;
JndiTemplate jndi = new JndiTemplate();
setJndiEnvironment(databaseProps, jndi);
try {
dataSource = jndi.lookup(databaseProps.getName(), DataSource.class);
} catch (NamingException e) {
logger.error("Exception loading JNDI datasource", e);
throw e;
}
return dataSource;
}
回答by Mayur
Since you are loading configuration class MyApplication.class
datasource bean will be created, Try moving datasource in another bean which is not used in a test, make sure all classes loaded for tests are not dependant on datasource.
Or
In your tests create a config class marked with @TestConfiguration
and include it in SpringBootTest(classes=TestConfig.class)
mocking data source there like
由于您正在加载配置类MyApplication.class
数据源 bean,因此尝试将数据源移动到另一个未在测试中使用的 bean 中,确保为测试加载的所有类不依赖于数据源。
或者
在您的测试中创建一个标记为的配置类@TestConfiguration
并将其包含在SpringBootTest(classes=TestConfig.class)
模拟数据源中,例如
@Bean
public DataSource dataSource() {
return Mockito.mock(DataSource.class);
}
But this may fail since method call to this mocked datasouce for connection will return null, In that case, you'll have to create an in-memory datasource and then mock jdbcTemplate and rest of dependencies.
但这可能会失败,因为对这个模拟数据源的连接方法调用将返回 null,在这种情况下,您必须创建一个内存数据源,然后模拟 jdbcTemplate 和其余依赖项。
回答by wjans
Try adding your datasource as a @MockBean
too:
尝试将您的数据源添加为@MockBean
:
@MockBean
private DataSource dataSource
That way Spring will do the replacing logic for you, having the advantage that your production code bean creation won't even be executed (no JNDI lookup).
这样 Spring 将为您执行替换逻辑,其优势在于您的生产代码 bean 创建甚至不会被执行(没有 JNDI 查找)。