请看这里:Junit4 简单教程 和 Spring Boot Junit单元测试
请看这里:强大的Mockito测试框架 和 Junit学习笔记之五:MockMVC
Jar包版本说明:
- junit:junit:4.12,
- org.mockito:mockito-core:1.10.19
请注意观察父子类之间各个函数执行的顺序:
public class MyTest1GrandFather {
@BeforeClass
public static void grandFatherBeforeClass() {
System.out.println("MyTest1GrandFather.beforeClass");
}
@AfterClass
public static void grandFatherAfterClass() {
System.out.println("MyTest1GrandFather.afterClass");
}
}
public class MyTest1Father extends MyTest1GrandFather {
@BeforeClass
public static void fatherBeforeClass() {
System.out.println("MyTest1Father.beforeClass");
}
@Before
public void fatherBefore1() {
System.out.println("MyTest1Father.before1");
}
@Before
public void fatherBefore2() {
System.out.println("MyTest1Father.before2");
}
@After
public void fatherAfter1() {
System.out.println("MyTest1Father.after1");
}
@After
public void fatherAfter2() {
System.out.println("MyTest1Father.after2");
}
@AfterClass
public static void fatherAfterClass() {
System.out.println("MyTest1Father.afterClass");
}
}
package hib;
import org.junit.*;
public class MyTest1 extends MyTest1Father {
@BeforeClass
public static void beforeClass() {
System.out.println("MyTest1.beforeClass");
}
@Before
public void before2() {
System.out.println("MyTest1.before2");
}
@Before
public void before1() {
System.out.println("MyTest1.before1");
}
@Before
public void before3() {
System.out.println("MyTest1.before3");
}
@Test
public void test2() throws Exception {
System.out.println("MyTest1.test2");
}
@Test
public void test1() throws Exception {
System.out.println("MyTest1.test1");
}
@Ignore
@Test
public void test3() throws Exception {
System.out.println("MyTest1.test3");
}
@After
public void after1() {
System.out.println("MyTest1.after1");
}
@After
public void after2() {
System.out.println("MyTest1.after2");
}
@AfterClass
public static void afterClass() {
System.out.println("MyTest1.afterClass");
}
}
MyTest1的测试结果:
MyTest1GrandFather.beforeClass
MyTest1Father.beforeClass
MyTest1.beforeClass
MyTest1Father.before2
MyTest1Father.before1
MyTest1.before3
MyTest1.before2
MyTest1.before1
MyTest1.test1
MyTest1.after1
MyTest1.after2
MyTest1Father.after1
MyTest1Father.after2
MyTest1Father.before2
MyTest1Father.before1
MyTest1.before3
MyTest1.before2
MyTest1.before1
MyTest1.test2
MyTest1.after1
MyTest1.after2
MyTest1Father.after1
MyTest1Father.after2
Test ignored.MyTest1.afterClass
MyTest1Father.afterClass
MyTest1GrandFather.afterClass
说明:
1. 从现象上看
@Before注解是按照函数名的字典序的倒序执行的,@After注解是按照函数名的字典序的正序执行的,但是并没有文档做出说明,所以不能依赖此顺序。
2. 分析源码可以看出(见下面的3张图片)
Test类里的函数先会进行一次排序,排序是先根据hashCode排;如果hashCode一样,再用函数名按照字典序升序排;如果函数名也一样,就用函数toString()的结果排。
上面的排序完成后,Before和BeforeClass注解的会逐个插入到执行队列的前面,其它的逐个插入到执行队列的后面。
但是文档中并没有给出承诺,所以还是不能依赖此顺序。
package test;
import org.junit.runner.RunWith;
import org.springframework.boot.context.embedded.LocalServerPort;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
@ActiveProfiles({"test"})
@RunWith(SpringRunner.class)
@SpringBootTest(classes = VotingApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class BaseTest {
@LocalServerPort
protected int port;
}
package test;
import hib.entity.StudentDao;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
public class MyTest2 extends BaseTest {
@Autowired
StudentDao studentDao;
@Test
public void test() throws Exception {
System.out.println(studentDao.count()); //1
}
}
参考:
[1] 使用@SpringBootTest注解进行单元测试
[2] Spring boot 单元测试
package test;
import org.junit.Test;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import static org.mockito.Mockito.when;
public class MyTest3 extends BaseTest {
@Autowired
service s1;
@Mock
service s2;
@Test
public void test() throws Exception {
System.out.println(s1.st1()); //hello
System.out.println(s2.st1()); //null
when(s2.st1()).thenReturn("123");
System.out.println(s2.st1()); //123
}
}
package hib;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MvcResult;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
public class MyTest4 extends ControllerTest {
@Autowired //负责找到controller
@InjectMocks //负责把MyTest4中所有有@Mock注解的对象注入到controller中
controller c1; //这里2个注释都要有,缺一不可
@Mock
service s1; //模拟service
@Test
public void test() throws Exception {
//1.模拟service中st1()的行为,本来应该返回hello,模拟后返回123
when(s1.st1()).thenReturn("123");
//2.模拟请求
MvcResult res = mvc.perform
(
get("/test/t1") //请求路径
.contentType(MediaType.APPLICATION_FORM_URLENCODED) //请求类型
.param("args", "root") //请求参数
)
.andExpect(status().isOk()) //预测返回状态
.andExpect(content().string("123")) //预测返回结果1
.andDo(print()) //执行回调函数
.andReturn(); //返回MvcResult对象
//3.断言返回结果2,和上面预测返回结果1处的作用相同
assertEquals("123", res.getResponse().getContentAsString());
}
}
分层设计测试架构,提取公共的初始化部分和测试业务。参见第3节-最佳实践。