78 单独执行项目的两个单元测试都没有问题, 但是 mvn install 执行单元测试其中一个报错

Posted 蓝风9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了78 单独执行项目的两个单元测试都没有问题, 但是 mvn install 执行单元测试其中一个报错相关的知识,希望对你有一定的参考价值。

前言

是这样的, 我最近有一个 HXRepository 的一个项目, 主要是 桥接的是各个类型的数据库的 BaseRepository, 相当于 我只需要依赖 HXRepository 以及 对应数据库的 driver, 然后 我的实体对应的 Repository 继承自 AbstractPostgres/Sqlite/mysqlEntityJdbcRepository 等等 Repository 就可以使用常用的增删改查了 

然后 我的 application.properties 在配置好对应的数据源的相关信息, 我的 实体对应的 Repository 就可以直接 增删改查了 

然后 这里出现的问题是 我的单元测试, 显然对于这种基础服务 是要做好足够的单元测试, 才能放心, 对于现在的功能, 对于以后的调整, 单元测试都可以起到至关重要的功能  

问题现象

我这里有两个单元测试, Test01SqliteTradeRepository 继承自 SqliteBaseRepositoryTest, Test01PostgresTradeRepository 继承自 PostgresBaseRepositoryTest 

SqliteBaseRepositoryTest 的内容大致是如下, PostgresBaseRepositoryTest 的内容也是大致如下, 只是二者 加载的不同的 application.properites[加载的不同的数据源] 

以及 Test01SqliteTradeRepository, Test01PostgresTradeRepository 测试的 SqliteTradeRepository 继承自 SqliteBaseRepository, PostgresTradeRepository 继承自 PostgresBaseRepository 

SpringContext.init 如下 

单独执行 Test01SqliteTradeRepository, 和单独执行 Test01PostgresTradeRepository 是都没有问题的, 所有的单元测试都 pass 

但是当我 mvn install HXRepository 这个项目的时候, 他会跑单元测试, 这个时候 就 Test01PostgresTradeRepository 报错了, 呵呵 这个让我 一度很郁闷 

甚至有点不太清楚 调试的方向在哪里 

问题的调试

当然 那也只是一时有一些懵逼了, 呵呵 很快还是找到了办法, 虽然不能 直接调试, 还可以 输出一下一些上下文的信息阿? 

下面的记录是当时 记录下来的上下文的记录的信息, 打印的是查询所使用的 jdbcTemlpate 和 dataSource 的信息 

可以看到的是 单独执行 Test01PostgresTradeRepository 的时候, dataSource 使用的是 postgres 的相关数据源, 但是 mvn install 的时候执行 Test01PostgresTradeRepository dataSource 使用的是 sqlite 相关的数据源 

呵呵 这个是怎么回事呢??, 想了一下 多半是与 SpringContext.init 有关系, context 不为 null, 使用的是已有的上下文 

Test01SqliteTradeRepository 执行在前, 先加载了 sqlite 相关的 applicationContext, Test01PostgresTradeRepository 执行的时候 applicationContext 不为空, 因此使用的是已有的 sqlite 的上下文 

然而 单独执行 Test01SqliteTradeRepository, Test01PostgresTradeRepository 都是新建的对应的需要的 applicationContext, 所以能够执行成功 

# 单独执行单元测试的时候的上下文 Test01PostgresTradeRepository
"queryTimeout":"-1","maxRows":"-1","lazyInit":"true","ignoreWarnings":"true","fetchSize":"-1","skipUndeclaredResults":"false","skipResultsProcessing":"false","resultsMapCaseInsensitive":"false"
"schema":"null","exceptionOverrideClassName":"null","validationTimeout":"5000","catalog":"null","isIsolateInternalQueries":"false","connectionInitSql":"null","transactionIsolationName":"null","password":"YYY2018!","isReadOnly":"false","isAutoCommit":"true","dataSourceClassName":"null","connectionTimeout":"60000","poolName":"null","minIdle":"5","isAllowPoolSuspension":"false","initializationFailTimeout":"1","sealed":"false","dataSourceJndiName":"null","leakDetectionThreshold":"0","maxLifetime":"300000","idleTimeout":"60000","connectionTestQuery":"null","driverClassName":"org.postgresql.Driver","jdbcUrl":"jdbc:postgresql://localhost:5432/hxrepo","maxPoolSize":"50","isRegisterMbeans":"false","username":"postgres"

# mvn install 的时候, 执行单元测试的时候的上下文 Test01PostgresTradeRepository
"queryTimeout":"-1","maxRows":"-1","lazyInit":"true","ignoreWarnings":"true","fetchSize":"-1","skipUndeclaredResults":"false","skipResultsProcessing":"false","resultsMapCaseInsensitive":"false"
"schema":"null","exceptionOverrideClassName":"null","validationTimeout":"5000","catalog":"null","isIsolateInternalQueries":"false","connectionInitSql":"null","transactionIsolationName":"null","password":"null","isReadOnly":"false","isAutoCommit":"true","dataSourceClassName":"null","connectionTimeout":"60000","poolName":"HikariPool-1","minIdle":"5","isAllowPoolSuspension":"false","initializationFailTimeout":"1","sealed":"true","dataSourceJndiName":"null","leakDetectionThreshold":"0","maxLifetime":"300000","idleTimeout":"60000","connectionTestQuery":"null","driverClassName":"org.sqlite.JDBC","jdbcUrl":"jdbc:sqlite:/Users/jerry/IdeaProjects/HXRepository/src/test/resources/trade.sqlite3","maxPoolSize":"50","isRegisterMbeans":"false","username":"null"

然后 最后, SpringContext 增加了一个 destroy, 在一个单元测试类所有 case 跑完之后 清理一下 SpringContext, 呵呵 解决问题 

呵呵 多从日常生活中学习调试的相关技能技巧, 调试方法千千万, 掌握好调试的技巧, 会让你受益颇深的 

上面打印出 JdbcTemlpate, DataSource 使用的是如下 api, 过滤掉了一部分的复杂对象[也并不需要这部分对象], 因此 是可以直接打印出来, 否则需要级联很多的东西 

使用如下 api 打印给定的对象的一部分信息, 方便于调试 

    /**
     * 调试 api, 将对象转换为 json, 去掉一部分基础类型之外的字段
     *
     * @param obj obj
     * @return com.alibaba.fastjson.JSONObject
     * @author Jerry.X.He
     * @date 2021-02-03 13:55
     */
    public static JSONObject castObject2JsonSimplify(Object obj) 
        ClassInfo classInfo = ClassInfoUtils.getClassInfo(obj.getClass());
        List<FieldInfo> allFieldList = classInfo.allFieldInfo();

        JSONObject result = new JSONObject();
        for (FieldInfo fieldInfo : allFieldList) 
            Class fieldType = fieldInfo.getField().getType();
            Field field = fieldInfo.getField();
            if (ClassUtils.isPrimitiveOrWrapperClass(fieldType)
                || ClassUtils.isStringClass(fieldType)
                || ClassUtils.isNumberClass(fieldType)) 
                String fieldName = fieldInfo.getFieldName();
                field.setAccessible(true);
                try 
                    String fieldValue = String.valueOf(field.get(obj));
                    result.put(fieldName, fieldValue);
                 catch (Exception e) 
                    // ignore
                
            
        
        return result;
    

完 

以上是关于78 单独执行项目的两个单元测试都没有问题, 但是 mvn install 执行单元测试其中一个报错的主要内容,如果未能解决你的问题,请参考以下文章

78 单独执行项目的两个单元测试都没有问题, 但是 mvn install 执行单元测试其中一个报错

在使用 Cocoapods 的项目中执行单元测试时,“两个都实现了 Class X”

(15)SpringBoot使用Junit单元测试

项目中的每个测试都说“从实时单元测试中排除”?

Django单元测试

当所有单独的测试都通过时,为啥我的 Bazel 测试报告失败?