Spring Boot 单元测试中的Sping Boot 数据源

l3zydbqr  于 2023-06-05  发布在  Spring
关注(0)|答案(2)|浏览(163)

我有一个简单的Sping 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
}

我有一个DataSource bean,它是在应用程序的主配置中配置的。当我运行测试时,Spring试图加载上下文并失败,因为DataSource是从JNDI获取的。一般来说,我希望避免为这个测试创建DataSource,因为我已经模拟了存储库。
在运行单元测试时,是否可以跳过DataSource的创建?

**注意:**内存数据库不支持测试,因为我的数据库创建脚本有特定的结构,无法从classpath:schema.sql轻松执行
编辑

数据源在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;
   }
toe95027

toe950271#

由于您正在加载配置类MyApplication.class datasource bean将被创建,请尝试将datasource移动到另一个未在测试中使用的bean中,确保为测试加载的所有类都不依赖于datasource。
或者
在测试中,创建一个标记为@TestConfiguration的配置类,并将其包含在SpringBootTest(classes=TestConfig.class)模拟数据源中,如

@Bean
public DataSource dataSource() {
    return Mockito.mock(DataSource.class);
}

但这可能会失败,因为方法调用这个模拟的数据源连接将返回null,在这种情况下,您必须创建一个内存中的数据源,然后模拟jdbcTemplate和其余的依赖项。

rggaifut

rggaifut2#

尝试将您的数据源也添加为@MockBean

@MockBean
private DataSource dataSource

这样Spring将为您执行替换逻辑,其优点是您的生产代码bean创建甚至不会被执行(没有JNDI查找)。

相关问题