Junit断言扩展

Assert.assert,断言,是大家JAVA单元测试必用的语句。根据个人的体验,Assert颇有不便之处:

1. Assert可以输入一个message,失败的时候,会把这个message打印出来,开发人员就知道错误是什么;开发人员也可以选择不输入message,这样失败了就什么都看不到;

2. Assert的工具不够多,比如没有函数直接支持 a 大于 5这样的断言, 也不能断言一个list包含另一个list;

问题是,单测本来是耗时耗力的事情,并且99%的断言都是不fail的,并且要写一个能解决问题的message很困难,于是很多人养成了不写message的习惯。然而,如果某个case在本地是好的,但是另一个环境 fail了,开发者打破脑袋也想不出来为什么,唯一的办法就是加个message,再次提交,再次fail。

我认为导致这个问题的原因是:junit的断言,是断言真假,而不是断言变量。

两者的区别是:断言真假,只知道结果是true或者false;断言变量,不仅能知道true和false,还知道参与断言的变量是什么。

如果断言fail,我们可以把参与断言的变量tostring打印出来。这样既能节约开发人员的时间,又能全面的获得fail时的上下文,便于排查问题。

基于junit的assert,可以很容易的扩展出基于变量的断言,比如下面的断言。无须任何message,但是如果断言失败,打印出的message足以告知出错的原因。

/**

     * 断言某个List包含另一个List的所有元素。

     * @param actual

     * @param expected

     */

public static <T> void assertContains(List<T> actual, List<T> expected){

        String actualStr = join(actual,",",100);

        String expectedStr = join(actual,",",100);

        //省略…

Assert.assertTrue("\nactual="+actualStr+"\nexpected="

+expectedStr+"\nmissed="+missedStr, missed.isEmpty());

    }

有时候用户的class可能不会实现tostring方法,这是即使把obj打印出来也没大用。所以我使用了一个强制输出string的办法,如下所示:

/**
     * 如果obj重载了toString,直接使用,否则用bean utils打印出所有的属性。
     * @param obj
     * @param clz
     * @return
     */
    public static <T> String toString(Object obj){
        try{
            Class<?> clz = obj.getClass();
            if(clz.getMethod("toString").getDeclaringClass().equals(obj.getClass())){
                return obj.toString();
            }else{
                return String.valueOf(BeanUtils.describe(obj));
            }
        }catch(Exception ex){
            return "Error in toString:"+ex.getMessage();
        }
    }

原文地址:https://www.cnblogs.com/alphablox/p/3041428.html