eclipse-junit单元测试

一,基础注解

junit的基础注解有@BeforeClass,Before,Test(),After,@AfterClass

执行顺序为:@BeforeClass>Before>Test1>After>Before>Test2>After>AfterClass

具体用法看一下代码:


public class Demo1Test {
    /**
     * BeforeClass注解的方法,应当为静态(static)的,且该方法在测试中只会执行一次,在第一个测试方法(即在第一个被test注解的方法)之前运行。
     * 常用于执行计算代价很大的任务,如打开数据库连接
     */
    @BeforeClass
    public static void connect() {
        System.out.println("数据库连接");
    }
    
    
    /**
     * 被before注解的方法会在每一个测试方法(被test()注解的方法)运行前执行一次。
     * 常用于初始化测试方法的资源。
     */
    @Before
    public void testInit() {
        System.out.println("初始化test");
    }
    
    /**
     * 被test注解的方法为要测试的代码。其中有俩个参数:1.expected 表示此测试方法执行后应该抛出的异常;2。timeout 检测测试方法的执行时间。
     * test中应当有使用断言来判断代码是否成功。
     */
    @Test(expected = ArithmeticException.class)
    public void test1() {
        //判断第一个参数(预期结果)是否与第二个参数(实际结果)相等。
        //若断言为假则会爆出expected的值ArithmeticException(算数异常)
        System.out.println("执行单元测试2");
        assertEquals(1, 2);
        
    }
    
    /**
     * timeout的单位为毫秒,测试方法中休眠俩秒,导致测试方法的执行时间大于1.1秒,因此会爆出异常(TestTimedOutException)。
     * 
     */
    @Test(timeout = 1100)
    public void test2() {
        try {
            //休眠俩秒
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException ie) {
            Thread.currentThread().interrupt();
        }
        System.out.println("执行单元测试2");
    }
    
    /**
     * 该类型的方法被用来关闭由@Before注解修饰的测试方法打开的资源。
     */
    @After
    public void closetest() {
        System.out.println("closstest");
    }
    
    /**
     * 该方法也是只会执行一次,且只会在最后一个测试方法执行完之后执行。同时该方法也应当为静态方法。
     * 该类型的方法被用来关闭由@BeforeClass注解修饰的测试方法打开的资源,如关闭数据库连接。
     */
    @AfterClass
    public static void close() {
        System.out.println("close");
    }

}

用例执行结果

test1方法中断言结果为假,爆出算数错误

test2中运行时间超过1.1秒,导致出现“”超时“”错误。

二、junit断言

1.junit4 assert断言

1.1.1例子如下


public class AssertTest {
    /**
     * assertEquals(Object expected, Object actual)检查俩个参数是否相等,可以检查基础数据类型和引用数据类型等。expected为预期的,actual为实际的。
     */
    @Test
    public void testAssertEquals() {
        Demo1 d1 = new Demo1(1, 1);
        Demo1 d2 = new Demo1(1, 1);
        //检查两个引用数据类型是否相等时,通过检查俩个对象的地址来判断是否为同一个对象。同理,判断数组和集合时,应当也是通过检查地址来判断是否相等。
//        assertEquals(d1, d1);
//        assertEquals("asd", "asd");
        int [] a = {1,2,3};
        int [] b = {1,2,3};
        assertEquals(a, a);
//        assertEquals(2, 1);
    }
    
    
    /**
     * assertTrue(boolean condition)检查条件为真,condition翻译为:条件
     */
    @Test
    public void testAssertTrue() {
        assertTrue(2 > 1);
    }
    
    /**
     * assertFalse(boolean condition)检查条件为假,condition翻译为:条件
     */
    @Test
    public void testAssertFalse() {
        assertFalse(2 > 1);
    }
    /**
     * assertNotNull(Object object)检查对象不为空
     */
    @Test
    public void testAssertNotNull() {
        assertNotNull(new String());
    }
    /**
     * assertNull(Object object)检查对象为空
     */
    @Test
    public void testAssertNull() {
        assertNull(new String());
    }
    /**
     * 检查俩个对象是否不指向同一个对象,即俩个对象的引用地址不同,也可以判断基本数据类型是否不相等
     */
    @Test
    public void testAssertNotSame() {
        Demo1 d1 = new Demo1(1, 1);
        Demo1 d2 = new Demo1(1, 1);
        assertNotSame(d1, d2);
//        assertNotSame("string", "String");
    }
    /**
     * 检查俩个对象是否指向同一个对象,即俩个对象的引用地址相同,也可以判断基本数据类型是否相等。
     */
    @Test
    public void testAssertSame() {
        Demo1 d1 = new Demo1(1, 1);
        Demo1 d2 = new Demo1(1, 1);
        assertSame(d1, d2);
//        assertSame(1, 1);
    }
    
    /**
     * assertArrayEquals(Object[] expecteds, Object[] actuals)检查两个数组是否相等
     * 该方法与assertEquls的区别在于,assertEquls是根据俩个数组的引用地址来检查,而assertArrayEquals则会对数组中每一个元素的值进行判断
     */
    @Test
    public void testAssertArrayEquals() {
        int[] a = {1,2,3};
        int[] b = {1,2,3};
        int[] c = {1,2,2};
        //该方法会爆出错误,错误中的预期和实际结果都为16进制数字
//        assertEquals(a, b);
        //该方法不会爆出错误
        assertArrayEquals(a,b);
        //该方法爆出错误,因为俩个数组中最后一个元素的值不同。具体可以运行查看错误信息。
//        assertArrayEquals(a,c);
    }
}

1.1.2方法汇总

方法名称

作用

assertEquals(Object expected, Object actual)

检查俩个参数是否相等

assertTrue(boolean condition)

检查条件为真

assertFalse(boolean condition)

检查条件为假

assertNotNull(Object object)

检查对象不为空

assertNull(Object object)

检查对象为空

assertNotSame(Object unexpected, Object actual)

检查俩个对象是否不指向同一个对象

assertSame(Object expected, Object actual)

检查俩个对象是否指向同一个对象

assertArrayEquals(Object[] expecteds, Object[] actuals)

检查两个数组是否相等

2.junit4 assertThat断言

这是我所用的jar包版本

不知道是我自己的原因还是这个jar包的原因,要是想用assertThat断言需要在文件顶部导入方法。

而要是用*号的话也是导入不了的。

我们可以先看一下assertThat方法的形参。

第一个参数为Object类型,参数名为actual,可知,第一个参数为实际结果,而第二个参数为预期结果,这和assertEquls断言是不一样的。

第二个参数为Matcher类型的,Matcher译为匹配符,匹配符有一般匹配符,字符串相关匹配符,集合相关匹配符,数值相关匹配符这四种类型。其中泛型所定义的<? super Object>理解为只接受Object类型和Object类的父类。

要注意的是这里的Object是根据你所传入的数据类型来变换的

如我这里传入进去的为"mysql",方法中的形参类型也由Object变成String。

2.1一般匹配符断言

2.1.1具体例子如下:

//一般匹配符
public class GeneralMatches {
    /**
     *     allOf(Matcher<? super String> first, Matcher<? super String> second)表示,第一个参数(实际结果)必须满足allOf中所有的条件。
     * 由上面可以看出,allOf方法中的形参类型为匹配符(Mather).且该匹配符方法的形参类型应当为String类型或String类型的父类。
     */
    @Test
    public void testAllof() {
        assertThat("mysql", allOf(startsWith("my"),containsString("sq")));
    }
    
    
    /**
     *     anyOf(Matcher<String> first, Matcher<? super String> second)表示,第一个参数(实际结果)必须满足allOf中所有的条件。
     * 由上面可以看出,anyOf方法中的形参类型为匹配符(Mather).且该匹配符方法的形参类型应当为String类型或String类型的父类。
     */
    @Test
    public void testAnyOf() {
        assertThat("mysql", anyOf(startsWith("my"),containsString("sq1")));
    }
    
    
    /**
     *     anything()表示,无论什么条件,永远为true。
     */
    @Test
    public void testAnything() {
        assertThat("mysql", anything());
    }
    
    /**
     *     is(String value)表示,前面的实际结果与后面的预期结果相等.
     * 实际结果指的的assertThat方法中的第一个参数,预期结果指的的is中的参数。
     */
    @Test
    public void testIs() {
        assertThat("mysql", is("mysql"));
    }
    
    /**
     * not(String value)表示,前面的实际结果与后面的预期结果不等.
     * 实际结果指的的assertThat方法中的第一个参数,预期结果指的的is中的参数。
     */
    @Test
    public void testNot() {
        assertThat("mysql", not("123"));
    }
    
    /**
     *     both()表示,预期结果满足both中的条件和每一个and中的条件或任意一个or中的条件
     */
    @Test
    public void testBoth() {
        assertThat("mysql", both(containsString("my")).and(containsString("s1")).and(containsString("ql")).or(containsString("ql")));
    }
    
    /**
     *     值不为空
     */
    @Test
    public void testNotNullValue() {
        String str2 = "123";
        assertThat(str2, is(notNullValue()));
    }
    
    /**
     * 值为空
     */
    @Test
    public void testNullValue() {
        String str2 = "123";
        assertThat(str2, is(nullValue()));
    }
    
}
2.1.2方法汇总

方法名称

作用

allOf(Matcher<? super String> first, Matcher<? super String> second)

表示,第一个参数(实际结果)必须满足allOf中所有的条件。

anyOf(Matcher<String> first, Matcher<? super String> second)

表示,第一个参数(实际结果)必须满足allOf中所有的条件。

anything()

表示,无论什么条件,永远为true

is(String value)

表示,前面的实际结果与后面的预期结果相等.

not(String value)

表示,前面的实际结果与后面的预期结果不等.

both(Matcher<String> first)

表示,预期结果满足both中的条件和每一个and中的条件或任意一个or中的条件

notNullValue()

值不为空

nullValue()

值为空

2.2.junit4 字符串相关匹配符

2.2.1具体例子如下

//字符串相关匹配符
public class StringMatches {
    
    /**
     * containsString(String substring)表示,前面的字符串(实际结果)中包字符串substring。
     */
    @Test
    public void testContainsString() {
        assertThat("hello-java", containsString("-"));
    }
    
    
    /**
     * endsWith(String suffix)表示,前面的字符串(实际结果)中以字符串suffix结尾。
     */
    @Test
    public void testEndsWith() {
        assertThat("hello-java", endsWith("va"));
    }
    
    
    /**
     * startsWith(String prefix)表示,前面的字符串(实际结果)中以字符串prefix开头。
     */
    @Test
    public void testStartsWith() {
        assertThat("hello-java", startsWith("he"));
    }
    
    
    /**
     * equalTo(String operand)表示,检查前面的实际结果与operand相等则通过,可以用于字符串之间或对象之间。
     */
    @Test
    public void testEqualTo() {
        assertThat("hello-java", equalTo("hello-java"));
    }
    
    
    /**
     * equalToIgnoringCase(String expectedString)表示,前面的实际结果(字符串)在忽略大小写的情况下与expectedString相等则通过.。
     */
    @Test
    public void testEqualToIgnoringCase() {
        assertThat("hello-java", equalToIgnoringCase("HELLO-java"));
    }
    
    
    /**
     * equalToIgnoringWhiteSpace(String expectedString)表示,前面的实际结果(字符串)在忽略头尾任意个空格的情况下与expectedString相等则通过.。
     */
    @Test
    public void testEqualToIgnoringWhiteSpace() {
        assertThat("hello-java", equalToIgnoringWhiteSpace(" hello-java"));
    }

}
2.2.2方法汇总

方法名称

作用

containsString(String substring)

前面的字符串(实际结果)中包字符串substring。

endsWith(String suffix)

表示,前面的字符串(实际结果)中以字符串suffix结尾。

startsWith(String prefix)。

表示,前面的字符串(实际结果)中以字符串prefix开头

equalTo(String operand)

表示,检查前面的实际结果与operand相等则通过,可以用于字符串之间或对象之间。

equalToIgnoringCase(String expectedString)

表示,前面的实际结果(字符串)在忽略大小写的情况下与expectedString相等则通过.。

equalToIgnoringWhiteSpace(String expectedString)

表示,前面的实际结果(字符串)在忽略头尾任意个空格的情况下与expectedString相等则通过。

2.3数值相关匹配符

2.3.1具体例子

//数值相关匹配符
public class NumMatches {
    /*
     * closeTo(double operand, double error)。
     * operand译为操作数,error译为误差,该方法的作用为,实际结果在{operand-error,poerand+error}区间则测试通过。注意,该区间为开区间。
     */
    @Test
    public void testCloseTo() {
        assertThat(0.971, is(closeTo(1.0, 0.03)));
    }
    /*
     * greaterThan(Integer value),当实际结果大于value时(不包括等于),则测试通过
     */
    @Test
    public void testGreaterThan() {
        assertThat(2, is(greaterThan(1)));
    }
    /*
     * lessThan(Integer value),当实际结果小于value时(不包括等于),则测试通过
     */
    @Test
    public void testLessThan() {
        assertThat(1, is(lessThan(0)));
    }

    /*
     * greaterThanOrEqualTo(Double value),当实际结果大于等于value时,则测试通过
     */
     
    @Test
    public void testGreaterThanOrEqualTo() {
        assertThat(1.03, is(greaterThanOrEqualTo(1.0)));
    }
    
    /*
     * lessThanOrEqualTo(Double value),当实际结果小于等于value时,则测试通过
     */
    @Test
    public void testLessThanOrEqualTo() {
        assertThat(1.0, is(lessThanOrEqualTo(1.0)));
    }

}
2.3.2方法汇总

方法名

作用

closeTo(double operand, double error)

实际结果在{operand-error,poerand+error}区间则测试通过。注意,该区间为开区间。

greaterThan(Integer value)

当实际结果大于value时(不包括等于),则测试通过

lessThan(Integer value)

当实际结果小于value时(不包括等于),则测试通过

greaterThanOrEqualTo(Double value)

当实际结果大于等于value时,则测试通过

lessThanOrEqualTo(Double value)

当实际结果小于等于value时,则测试通过

2.4集合相关匹配符

2.4.1具体例子

//集合相关匹配符
public class ArraysMatchers {
    // 以下为List集合相关匹配符。
    /*
     * everyItem(Matcher<String> itemMatcher)
     * 实际结果的集合中,每一项都要满足itemMatcher的条件,即如下例子所示,集合中每一项都要以m开头,测试才通过。
     */
    @Test
    public void testEveryItem() {
        assertThat(Arrays.asList("my", "asList"), everyItem(startsWith("m")));
    }

    /*
     * hasItem(String item) 实际结果的集合中,包含item这个元素,即如下例子所示,集合中要有一个元素为123,测试才通过。
     */
    @Test
    public void testHasItem() {
        List<String> l = new ArrayList();
        l.add("123");
        l.add("asd");
        l.add("123");
//        assertThat(Arrays.asList("my","asList"),hasItem("my"));
        assertThat(l, hasItem("123"));
    }

    /*
     * hasItems(String... items),该方法中使用了...符号,代表该方法形参的个数是可变的,但是类型必须为String类型。
     * 该方法表示:在实际结果的集合中,集合要包含多个元素,即如下例子所示,集合中要有元素为123和asd,测试才通过。
     */
    @Test
    public void testHasItems() {
        List<String> l = new ArrayList();
        l.add("123");
        l.add("asd");
        assertThat(l, hasItems("123", "asd"));
    }

    /*
     * isIn(Collection<String> collection)该方法表示,实际结果与collection集合中的一个元素相等,则测试通过。
     */
    @Test
    public void testIsIn() {
        List<String> l = new ArrayList();
        l.add("123");
        l.add("asd");
        assertThat("123", isIn(l));
    }

    /*
     * empty()表示实际结果(集合)为空集合。
     */
    @Test
    public void testEmpty() {
        List<String> l = new ArrayList();
        assertThat(l, empty());
    }

    /*
     * hasSize(int size)表示实际结果(集合)的长度为size。
     */
    @Test
    public void testHasSize() {
        List<String> l = new ArrayList();
        l.add("123");
        assertThat(l, hasSize(1));
    }

    // 以下的匹配符与map集合相关。

    /*
     * hasEntry(String key, String value),map集合中包含特定的键(key)值(value)对。
     */
    @Test
    public void testHasEntry() {
        Map<String, String> m = new HashMap<String, String>() {
            {
                put("1", "励志名言");
                put("2", "爱情名言");
            }
        };
        assertThat(m, hasEntry("2", "爱情名言"));
    }

    /*
     * hasKey(String key),map集合中包含特定的键(key)。
     */
    @Test
    public void testHasKey() {
        Map<String, String> m = new HashMap<String, String>() {
            {
                put("1", "励志名言");
                put("2", "爱情名言");
            }
        };
        assertThat(m, hasKey("2"));
    }

    /*
     * hasValue(String value),map集合中包含特定的值(value)。
     */
    @Test
    public void testHasValue() {
        Map<String, String> m = new HashMap<String, String>() {
            {
                put("1", "励志名言");
                put("2", "爱情名言");
            }
        };
        assertThat(m, hasValue("爱情名言"));
    }

    // 以下为数组相关匹配符
    @SuppressWarnings("unchecked")
    /*
     * array(Matcher<? super Integer>... elementMatchers)该方法中的形参个数是可变的。
     * 用处:实际结果中数组长度相等且对应元素也相等
     */
    @Test
    public void testArray() {
        Integer[] a = { 1, 2, 3, 4 };
        assertThat(a, is(array(equalTo(1), equalTo(2), equalTo(3), equalTo(4))));

    }

    /*
     * hasItemInArray(Integer element)数组是否包含元素element
     */
    @Test
    public void testHasItemInArray() {
        Integer[] a = { 1, 2, 3, 4 };
        assertThat(a, hasItemInArray(1));
    }
    /*
     * arrayContainingInAnyOrder(Integer... items)忽略顺序,长度相等以及数组元素中的值都有
     */
    @Test
    public void testArrayContainingInAnyOrder() {
        Integer[] a = { 1, 2, 3, 4 };
        assertThat(a, arrayContainingInAnyOrder(1, 3, 2, 4));
    }
    /*
     * arrayContaining(Integer... items),要顺序,长度以及元素都一致。
     */
    @Test
    public void testArrayContaining() {
        Integer[] a = { 1, 2, 3, 4 };
        assertThat(a, arrayContaining(1, 2, 3, 4));
    }
}
2.4.2方法汇总

everyItem(Matcher<String> itemMatcher)

实际结果的集合中,每一项都要满足itemMatcher的条件

hasItem(String item)

实际结果的集合中,包含item这个元素

hasItems(String... items)

在实际结果的集合中,集合要包含多个元素

isIn(Collection<String> collection)

实际结果与collection集合中的一个元素相等,则测试通过

empty()

表示实际结果(集合)为空集合

hasSize(int size)

表示实际结果(集合)的长度为size

hasEntry(String key, String value)

map集合中包含特定的键(key)值(value)对。

hasKey(String key)

map集合中包含特定的键(key)。

hasValue(String value)

map集合中包含特定的值(value)。

array(Matcher<? super Integer>... elementMatchers)

实际结果中数组长度相等且对应元素也相等

hasItemInArray(Integer element)

数组是否包含元素element

arrayContainingInAnyOrder(Integer... items)

忽略顺序,长度相等以及数组元素中的值都有

arrayContaining(Integer... items)

要顺序,长度以及元素都一致。

三、junit参数化

例子如下:


//1.使用@RunWith(Parameterized.class)注释测试类。
@RunWith(Parameterized.class)
public class ParameterTest {
    //2.声明测试数据变量。
    private String parameter;//被测方法需要传入的参数
    private String expect;//预期结果
    
    //3.创建构造函数,用于初始化测试数据。
    public ParameterTest(String parameter, String expect) {
        super();
        this.parameter = parameter;
        this.expect = expect;
    }
    //4.创建一个使用@Parameters注释的公共静态方法,该方法返回一个二维集合作为测试数据集。其中每一行都为一组测试数据。
    @Parameters
    public static Collection<Object[]> Data() {
        return Arrays.asList(new Object[][] {
            {"李华","欢迎您:李华"},
            {"李四","欢迎您:李四"},
            {"王五","欢迎您:王五"},
        });
    }
    //5.使用上面定义的变量作为测试数据进行测试。
    @Test
    public void test() {
        String result = Demo1.t1(parameter);
        System.out.println("parameter:" + parameter + ";" + "expect:" + expect);
        assertEquals(expect, result);
    }

}

运行结果如下:

输出如下:

四、JUnit测试套件

运用场景:开发中,测试类会越来越多,如果要一个个执行测试类会很麻烦,因此可以用测试套件批量执行测试类。

操作步骤:

  1. 创建三个测试类Test1,Test2,Test3


//测试类1
public class Test1 {

    @Test
    public void test() {
        System.out.println("测试一");
    }

}
//测试类2
public class Test2 {

    @Test
    public void test() {
        System.out.println("测试二");
    }

}

//测试类3
public class Test3 {

    @Test
    public void test() {
        System.out.println("测试三");
    }

}
  1. 创建俩个测试套件:TsetAll1,TestAll2(测试套件应当为空,里面没有任何代码块)

  1. 测试套件添加注解@RunWith(Suite.class)和@SuiteClasses({Test1.class,Test2.class})


//套件1
@RunWith(Suite.class)
@SuiteClasses({Test1.class,Test2.class})
public class TestAll1 {

    //@SuiteClasses注解中的Test1,Test2为需要测试的测试类,数量不止可以设置成2个,设置成三个或更多也行。
}
//套件二,测试套件之间是可以嵌套的,比如该套件,嵌套了套件1
@RunWith(Suite.class)
@SuiteClasses({TestAll1.class,Test2.class})
public class TestAll2 {


}

套件一输出结果:

套件二输出结果:

五、JUnit测试优先级顺序

JUnit是通过@FixMethodOrder注解(annotation)来控制测试方法的执行顺序的。@FixMethodOrder注解的参数是org.junit.runners.MethodSorters对象,在枚举类org.junit.runners.MethodSorters中定义了如下三种顺序类型:

MethodSorters.JVM:按照JVM得到的方法顺序,也就是代码中定义的方法顺序)

MethodSorters.DEFAULT(默认的顺序):以确定但不可预期的顺序执行

MethodSorters.NAME_ASCENDING:按方法名字母顺序执行

六、JUnit内置Rule

  1. TemporaryFolder Rule

使用 TemporaryFolderRule 能够创建临时文件和临时文件夹,在方法运行完成后会自动删除掉临时文件跟文件夹(但不校验删除是否成功)。


public class TemporaryFolderRuleTest {
    
    @Rule
    public TemporaryFolder tmpFolder = new TemporaryFolder();

    @Test
    public void test() throws IOException {
        //创建一个名称为test.txt的文件
        File file = tmpFolder.newFile("test.txt");
        System.out.println(file.getName());
    }
    
    @Test
    public void test1() throws IOException {
        //创建一个多级目录a/b的文件夹
        File file = tmpFolder.newFolder("a","b");
        System.out.println(file.getPath());
    }
    
    @Test
    public void test2() throws IOException {
        //创建一个随机名称的文件
        File file = tmpFolder.newFile();
        System.out.println(file.getName());
    }
    
    @Test
    public void test3() throws IOException {
        //创建一个随机名称的文件夹
        File file = tmpFolder.newFolder();
        System.out.println(file.getPath());
    }
    

}

但从 junit 4.13 开始,TemporaryFolder支持配置校验是否删除成功,删除失败则抛出AssertionError异常。且实例化的方式也有区别。



public class TemporaryFolderRuleTest {
    //
    @Rule
    public TemporaryFolder tmpFolder = TemporaryFolder.builder().assureDeletion().build();

    @Test
    public void test() throws IOException {
        //创建一个名称为test.txt的文件
        File file = tmpFolder.newFile("test.txt");
        System.out.println(file.getName());
    }
    
}
  1. ExpectedException Rule

ExpectedException 可以用来校验代码即将发生的异常:


public class ExpectedExceptionRuleTest {
    @Rule
    public ExpectedException thrown =ExpectedException.none();
    
    @Test
    public void test() {
        
        //预期的异常
        thrown.expect(RuntimeException.class);
        //异常原因
        thrown.expectCause(isA(IllegalAccessException.class));
        //异常的消息
        thrown.expectMessage("This is illegal");
        //抛出指定异常
        throw new RuntimeException("This is illegal", new IllegalAccessException());
    }

}
  1. Verifier Rule

Verifier 是一个抽象类,当我们需要在测试用例中验证一些额外的行为的时候,可以使用这个类并重写该类的 verify 方法。


public class VerifierRuleTest {
    
    private List messageLog = new ArrayList<>();
    @Rule
    public TestName name = new TestName();
    //在每个测试用例执行完的时候额外验证一下messageLog 是否为空
    @Rule
    public Verifier vf = new Verifier() {
        //该方法在测试方法执行完后执行,用于额外验证。
        @Override
        protected void verify() throws Throwable {
            System.out.println("vf");
            assertFalse("msg Log is not Empty!", messageLog.isEmpty());

        }
        //该方法为自定义Rule,在方法前后都可以执行,可用于初始化和关闭资源,且重写该方法后,verify方法将不会执行。
        @Override
        public Statement apply(Statement base, Description description) {
            // TODO Auto-generated method stub
            return new Statement() {
                
                @Override
                public void evaluate() throws Throwable {
                    System.out.println("测试开始" + name.getMethodName());
                    //执行测试方法
                    base.evaluate();
                    System.out.println("测试完成" + name.getMethodName());
                    
                }
            };
        }
        
        
        
    };
    
    @Test
    public void test() {
        System.out.println("测试1");
        messageLog.add("132");
    }
    
    @Test
    public void test1() {
        System.out.println("测试2");
    }

}
  1. ExternalResourceRule

当做集成测试的时候,有可能需要在执行前准备一些数据(可以是一个文件/数据库连接),并在执行完将准备的数据进行删除。这时候就可以用 ExternalResource Rule 实现。


public class ExternalResourceRuleTest {

    @Rule
    public ExternalResource re = new ExternalResource() {
        @Override
        protected void before() {
            System.out.println("数据库连接");
        }
        
        @Override
        protected void after() {
            System.out.println("关闭数据库连接");
        }
    };
    
    @BeforeClass
    public static void pulic() {
        System.out.println("1");
    }
    
    @Test
    public void test() {
        System.out.println("执行测试");
    }


}
  1. TestName Rule

该Rule可用于获取当前测试方法的方法名


public class VerifierRuleTest {
    
    //实例化TestName对象
    @Rule
    public TestName name = new TestName();
    
    @Test
    public void test() {
        //调用getMethodName()方法获取当前测试方法的名称。
        System.out.println("测试:" + name.getMethodName());
    }
}
  1. 自定义 Junit Rule

除了使用 junit 提供的默认 Rule 外,还可以自定义我们自己的 Rule, 自定义 Rule 需要继承 TestRule 接口,并实现其 apply 方法。


public class MyRuleTest {
    //2.实例化MyRule类
    @Rule
    public MyRule myRule = new MyRule();
    
    //3.执行(run)测试方法。
    @Test
    public void test() {
        System.out.println("测试一");
    }
    
    
    //1.自定义Rule类,实现TestRule接口,重写apply方法。
    class MyRule implements TestRule{
        //
        @Override
        public Statement apply(Statement arg0, Description arg1) {
            return new Statement() {
                
                @Override
                public void evaluate() throws Throwable {
                    //getClassName()方法用于获取当前类名
                    System.out.println("执行测试方法前" + arg1.getClassName());
                    //执行测试方法。
                    arg0.evaluate();
                    //getMethodName()方法用于获取当前测试方法名称。
                    System.out.println("执行测试方法后" + arg1.getMethodName());
                }
            };
        }
    }
}

  1. Rule链

当有多个 Rule 的时候,可以通过 RuleChain 来控制多个 Rule 的执行顺序


public class RuleChainsTest {

    @Rule
    public RuleChain ruleChain = RuleChain.outerRule(new SimpleMsgLogger("First Rule"))
            .around(new SimpleMsgLogger("Second Rule"))
            .around(new SimpleMsgLogger("Third Rule"));

    @Test
    public void test() {
        System.out.println("run case");
    }

    static class SimpleMsgLogger implements TestRule {

        private String log;

        public SimpleMsgLogger(String log) {
            this.log = log;
        }

        @Override
        public Statement apply(Statement base, Description description) {
            return new Statement() {
                @Override
                public void evaluate() throws Throwable {
                    System.out.println("Starting:" + log);
                    base.evaluate();
                    System.out.println("Finishing:" + log);
                }
            };
        }
    }

}

七、测试private方法


public class PrivateMethondTest {
     //实例化被测试类。
    Demo1 d = new Demo1();
    @Test
    public void test() throws Exception  {
         //测试没有参数的out()方法  
        Method method = d.getClass().getDeclaredMethod("out", null);
        //要访问私有方法必须将accessible设置为true,否则抛java.lang.IllegalAccessException
        method.setAccessible(true);
        //调用私有方法。
        Object rs = method.invoke(d, null);
        System.out.println(rs);
        assertNotNull(rs);
    }
    
    @Test
    public void test1() throws Exception  {
         //测试有参数的out()方法  
        Method method = d.getClass().getDeclaredMethod("out", String.class);
        //要访问私有方法必须将accessible设置为true,否则抛java.lang.IllegalAccessException
        method.setAccessible(true);
        //调用私有方法。
        Object rs = method.invoke(d, "123");
        System.out.println(rs);
    }
    
    @Test
    public void test2() throws Exception  {
         //测试有参数的out()方法  
        Method method = d.getClass().getDeclaredMethod("out", int.class);
        //要访问私有方法必须将accessible设置为true,否则抛java.lang.IllegalAccessException
        method.setAccessible(true);
        //调用私有方法。
        Object rs = method.invoke(d, 123);
        System.out.println(rs);
    }
}
  • 26
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值