浅谈junit(单元测试)

单元测试是被广大猿类使用的测试包,当你在跟团队做 java 开发时,往往面临三种选择:

  • 把整个 project 运行一下测试自己写的功能,可能会出现 project 启动慢,或者别人的代码有坑,导致 project 无法正常 run 的情况
  • 使用 junit ,可以帮你节省大量的时间,首先,运行 junit 不需要运行整个 project 节省时间,其次,junit 可以只测试某段代码,或者某几段代码的功能,因此可以减少其他代码的影响
  • 不测试就提交,呵呵…
    (1)@Test
    1
    2
    3
    4
    Test
    public void testMethod0(){
    System.out.println("test method 0");
    }

    用@Test修饰用于单元测试的方法。

    (2)@Before
    1
    2
    3
    4
    Before
    public void beforeMethod0(){
    System.out.println("before method 0");
    }

    被@Before修饰的方法会在@Test修饰的方法之前被执行;多个@Before修饰方法的执行顺序和书写顺序没有关系。

    (3)@After
    1
    2
    3
    4
    After
    public void afterMethod(){
    System.out.println("after method");
    }

    被@After修饰的方法会在@Test修饰的方法之后执行;多个@After的执行顺序和书写顺序无关。

注意: 当有多个@Before和多个@After修饰方法时 @Before修饰方法的执行顺序是名称的倒序 @After修饰方法的执行顺序是名称的顺序

(4)@Ignore
1
2
3
4
5
@Ignore
@Test
public void testMethod1(){
System.out.println("test method 1");
}

被@Ignore修饰的@Test方法不会在单元测试中被执行;@Ignore注解对@Before和@After修饰的方法不产作用。

(5)@BeforeClass
1
2
3
4
@BeforeClass
public static void beforeClass(){
System.out.println("before class");
}

被@BeforeClass修饰的方法会在junit的测试类实例化之前执行,所以必须保证@BeforeClass此之前就已经被编译,通常用的方法就是加static,如果@Test所修饰的method不是static的话。

(6)@AfterClass
1
2
3
4
@AfterClass
public void afterClass(){
System.out.println("after class");
}

被@AfterClass修饰的方法会在junit的测试类

(7)@Parameters & @Parameter

指定一些测试方法的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class DataOpration{

public static int add(int par1, int par2){
return (par1+par2);
}

}
@RunWith(Parameterized.class)
public class ParametersDemo {

@Parameters(name = "{index}:add({0}, {1})={2}")
//这里使用 Collection 和 Iterable 都行
public static Collection<Object[]> data(){
// public static Iterable<Object[]> data(){
return Arrays.asList(new Object[][]{
{1, 1, 2}, {1, 2, 3}, {2, 3, 5}
});
}

@Parameter(0)
public int par1;
@Parameter(1)
public int par2;
@Parameter(2)
public int sum;

@Test
public void test(){
assertEquals(sum, DataOpration.add(par1, par2));
}

}
(8)exception
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@Test(expected = NullPointerException.class)
public void testExceptionMessage0(){
String str = null;
if(str.equals(""));
}

@Test
public void testExceptionMessage1(){
try {
String str = null;
if(str.equals(""));
fail("Expected an NullPointerException to be thrown");
}catch (NullPointerException anNullPointerException){
System.out.println(anNullPointerException.getMessage());
Assert.assertThat(anNullPointerException.getMessage(), is(nullValue()));
}

}

@Test
public void testExceptionMessage2(){
try {
new ArrayList<Object>().get(0);
fail("Expected an IndexOutOfBoundsException to be thrown");
} catch (IndexOutOfBoundsException anIndexOutOfBoundsException) {
System.out.println(anIndexOutOfBoundsException.getMessage());
Assert.assertThat(anIndexOutOfBoundsException.getMessage(), is("Index: 0, Size: 0"));
}
}

@Rule
public ExpectedException shouldThrown = ExpectedException.none();
@Test
public void testExceptionMessage3() throws NullPointerException{
String str = null;
shouldThrown.expect(NullPointerException.class);
shouldThrown.expectMessage(new IsNull<String>());
if(str.equals(""));
}
@Test
public void testExceptionMessage4() throws IndexOutOfBoundsException{
shouldThrown.expect(IndexOutOfBoundsException.class);
shouldThrown.expectMessage("Index: 0, Size: 0");
new ArrayList<Object>().get(0);
}

使用junit测试抛出异常的方法有三种: 1、@Test(expected = XXXException.class) 2、Assert.assertThat(XXXException.getMessage(), expected value)); 3、@Rule ExpectedException expect expectMessage 注意:null这样的值要特殊处理(可见上述代码)

(9)Assert

断言,像 assertEquals、assertFalse、assertNotSame、assertNull、assertThat 等,具体用法见下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/**
* 比较两个数组是否相等
*/
@Test
public void arrayEqualsTest(){
int array1[] = {1, 2, 3};
int array2[] = {1, 2, 3};
Assert.assertArrayEquals("should be equal", array1, array2);
}

/**
* 把两个 new StringBuffer("222") 做个比较,方便下面的@Test结果预测
* 注:equals方法在没有重写的情况下比较的是两个object的物理地址
*/
@Test
public void compareTwoStringBuffer(){
System.out.println(new StringBuffer("222").equals(new StringBuffer("222")));
System.out.println((new StringBuffer("222")) == (new StringBuffer("222")));
}

/**
* 判断两个object是否相等
* 比较物理地址
*/
@Test
public void assertEquallsTest(){
Assert.assertEquals("should be equal", new StringBuffer("222"), new StringBuffer("222"));
}
/**
* 判断两个object是否不相等
* 比较物理地址
*/
@Test
public void assertNotEquallsTest(){
Assert.assertNotEquals("should be not equal", new StringBuffer("222"), new StringBuffer("222"));
}

/**
* 预期值为false
*/
@Test
public void assertFalseTest(){
Assert.assertFalse("should be false", (new StringBuffer("222")).equals(new StringBuffer("222")));
}

/**
* 预期值为true
*/
@Test
public void assertTrueTest(){
assertTrue("should be true", new StringBuffer("222").equals(new StringBuffer("222")));
}

/**
* 是否不相等
* 比较物理地址
*/
@Test
public void assesrtNotSameTest(){
Assert.assertNotSame("should be not same", new StringBuffer("222"), new StringBuffer("222"));
}

/**
* 是否为null的判断
*/
@Test
public void assertNullTest(){
Assert.assertNull("should be null", "");
}

/**
* 是否相等
* 比较物理地址
*/
@Test
public void assertSameTest(){
Integer integer = new Integer("35");
Assert.assertSame("should be same", integer, 35);
}

/**
* both .and 是连接符
* containsString 包含某个 String
*/
@Test
public void bothAndContainsStringTest(){
Assert.assertThat("baby",
both(containsString("ab")).and(containsString("by")));
}

/**
* hasItems 是否包含某个item
*/
@Test
public void hasItemsTest(){
Assert.assertThat(Arrays.asList(1, 2, 3), hasItems(1, 2));
}

/**
* everyItem 是不是每个item都满足XXX
*/
@Test
public void everyItemTest(){
Assert.assertThat(Arrays.asList(new String[]{"ab", "bc", "abc"}),
everyItem(containsString("b")));
}

@Test
public void hamcrestCoreMatchersTest(){
Assert.assertThat("nice", allOf(equalTo("nice"), startsWith("n")));
assertThat("good", not(allOf(equalTo("bad"), equalTo("good"))));
assertThat("good", anyOf(equalTo("bad"), equalTo("good")));
assertThat(7, not(CombinableMatcher.<Integer> either(equalTo(3)).or(equalTo(4))));
assertThat(new Object(), not(sameInstance(new Object())));
}
(10)spring & junit

spring和junit的结合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-junit-conf.xml")
@Rollback(true)
//@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
//注意在新的spring版本中,@TransactionConfiguration注解被@Commit和@Rollback取代了,详情见官方文档
public class SpringJunit0{

@Autowired
private SpringService springService;

@Test
public void testSpringServiceImplinsertStudent(){
try{
springService.insertStudent(new StudentModel());
}catch (Exception e){
e.printStackTrace();
}
}
}

maven dependency

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.17.RELEASE</version>
</dependency>
<!-- 使用@Autowired标签需要 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.17.RELEASE</version>
</dependency>
<!-- 使用@Transactional标签需要 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-hibernate3</artifactId>
<version>2.0.8</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.17.RELEASE</version>
</dependency>
</dependencies>

project url:https://github.com/Knight-JNXU/JavaFundation/tree/JunitStudy

|