美文网首页
Spring Cloud体系下,使用Junit 5、MyBati

Spring Cloud体系下,使用Junit 5、MyBati

作者: 听歌闭麦开始自闭 | 来源:发表于2024-02-17 10:55 被阅读0次

    情况说明

    在使用Spring Cloud体系时,Spring Boot 项目的启动会伴随着诸多第三方技术的客户侧/生产侧开始工作,
    例如Dubbo、Redis、Jetcd、Nacos、Zookeeper等服务,会去主动的完成注册、连接、发送心跳等行为。

    这些操作,对于单元测试而言是没有必要的,单元测试的核心原则不考虑这些内容。
    通常情况下,即使有需求,对于外部服务的调用也是通过Mock的形式,主动模拟外部接口的调用返回;
    但有些情况下,这种模拟本身就变得不正确了。

    例如,程序通过AOP、MyBatis插件的形式配合完成的SQL行级数据权限拼接,在这种情况下,SQL的完全体是不能预先获知的(实际上可以,但很麻烦),
    因此单元测试必须集成Spring、内存数据库、MyBatis (Plus)技术,完成对已有代码的的最小粒度测试。

    在上述案例的情况下,这个测试本身的目的 仍然是为了验证 Mapper/Dao 层的最终SQL是否可以正确执行,因此是符合横向单层测试的理念的,只是为了达到这个目的需要借助纵向穿透测试的使用,在我看来,这仍属于单元测试的范畴。

    代码示例

    @TestConfiguration
    public class MyBatisTestConfig {
    
        @Bean
        public DataSource dataSource() {
            return new EmbeddedDatabaseBuilder()
                    .setType(EmbeddedDatabaseType.H2)
                    .build();
        }
    
        @Bean
        public DataSourceInitializer dataSourceInitializer(DataSource dataSource) {
            ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
            populator.addScript(new ClassPathResource("sql/schemas-h2.sql"));
            populator.addScript(new ClassPathResource("sql/data-h2.sql"));
    
            DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
            dataSourceInitializer.setDataSource(dataSource);
            dataSourceInitializer.setDatabasePopulator(populator);
            dataSourceInitializer.setEnabled(true);
            return dataSourceInitializer;
        }
    
        @Bean(name = "h2WebServer", initMethod = "start", destroyMethod = "stop")
        public Server server() throws Exception {
            return Server.createWebServer("-web", "-webAllowOthers", "-webDaemon", "-webPort", "8082");
        }
    
        @Bean
        public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
            SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(dataSource);
            sessionFactory.setTypeAliasesPackage("xxx.xxx.xxx.xxx.entity");
    
            Configuration configuration = new Configuration();
            configuration.setCacheEnabled(false);
            configuration.setCallSettersOnNulls(true);
            configuration.setMapUnderscoreToCamelCase(true);
            configuration.setLogImpl(StdOutImpl.class);
            sessionFactory.setConfiguration(configuration);
    
            return sessionFactory.getObject();
        }
    
        @Bean
        public MapperScannerConfigurer mapperScannerConfigurer() {
            MapperScannerConfigurer configurer = new MapperScannerConfigurer();
            configurer.setBasePackage("xxx.xxx.xxx.xxx.mapper");
            configurer.setAnnotationClass(Mapper.class);
            configurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
            return configurer;
        }
    }
    
    
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, classes = {
            MyBatisTestConfig.class, IDemoMapper.class, IDemoService.class
    })
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @ExtendWith(MockitoExtension.class)
    @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
    public class IDemoServiceTest {
        @Autowired
        private IDemoService iDemoService;
    
        @Test
        void test() {
            Demo entity = iDemoService.selectById(1);
            Assertions.assertNotNull(entity);
            Assertions.assertEquals(1L, contact.getId());
        }
    }
    

    如果需要额外的Bean,在 @SpringBootTest 的classes中不断追加即可。

    相关文章

      网友评论

          本文标题:Spring Cloud体系下,使用Junit 5、MyBati

          本文链接:https://www.haomeiwen.com/subject/amjzvdtx.html