Spring boot 单元测试主要由Junit实现.
一.Junit介绍
1.Junit测试.
@RunWith(SpringRunner.class) @SpringBootTest public class TestConfig { @BeforeClass public static void beforeClass(){ System.out.println("单元测试开始之前执行初始化..."); System.out.println("-----------------------------------------------"); } @Before public void before(){ System.out.println("单元测试方法开始之前执行"); } @Test public void test1(){ assertEquals("比较结果: ", 20, 25 - 5); } @Test public void test2(){ assertEquals("比较结果", 12, 18 - 5); } @After public void after(){ System.out.println("单元测试方法结束之后执行"); } @AfterClass public static void afterClass(){ System.out.println("-----------------------------------------------"); System.out.println("单元测试结束之后执行清除..."); } }
@BeforeClass 及@AfterClass 是静态方法.
2.测试验证使用Junit中Assert类的assert方法.
assertEquals("message", A, B) 判断两个对象内容是否相等
assertSame("message", A, B) 判断两个对象是否为同一个
assertTrue("message", A) 判断A是否为真
assertFalse("message", A) 判断A是否为假
assertNotNull("message", A) 判断A是否为非空
assertArrayEquals("message", A, B) 判断数组A, B是否相等
3.Suite一次运行一个或多个测试用例
@RunWith(Suite.class) @Suite.SuiteClasses({EnvConfigTest.class, TestConfig.class}) public class SuiteTest { }
二.Springboot单元测试
POM中添加依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency>
1.测试脚手架
springboot使用注解来增强单元测试以支持springboot测试.实例:
@RunWith(SpringRunner.class) @SpringBootTest public class TestConfig { }
@RunWith是Junit标准的注解,告诉Junit单元测试框架使用指定的类来进行单元测试.
@SpringBootTest用于测试Springboot应用程序, 通过启动App程序入口来加载上下文.
2.测试Service
@RunWith(SpringRunner.class) @SpringBootTest @Transactional public class UserServiceImplTest { @Autowired private UserService userService; @MockBean private CreditSystemService creditSystemService; @Test public void getCredit() { int userId = 10; int expectedCredit = 100; given(creditSystemService.getUserCredit(anyInt())).willReturn(expectedCredit); int credit = userService.getCredit(userId); assertEquals(expectedCredit, credit); }
@MockBean 注入CreditSystemService, given模拟getCredit方法.
以后可以先写接口在写实现.
3.测试MVC
@RunWith(SpringRunner.class) @WebMvcTest(UserController.class) public class UserControllerTest { @Autowired private MockMvc mockMvc; @MockBean private UserService userService; @Test public void getCredit() throws Exception { int userId = 10; int expectedCredit = 100; given(userService.getCredit(userId)).willReturn(expectedCredit); mockMvc.perform(get("/user/getCredit/{id}",userId)) .andExpect(content().string(String.valueOf(expectedCredit))); } @Test public void getUser() throws Exception { int id = 10; String name = "pangyazhou"; String message = "hello, world"; mockMvc.perform(post("/user/getUser/{id}/{name}", id, name).param("message", "hello").param("sex", "male", "female")) .andExpect(content().string("ok")); } @Test public void test1() throws Exception { mockMvc.perform(get("/user/test").param("message", "hello,world")) .andExpect(content().string("ok")); } }
@WebMvcTest表明这是一个MVC测试,参数可以传入多个待测试的Controller类.
MockMvc是Spring提供的专门用于测试SpringMVC类.
@MockBean用于模拟实现, 在SpringMvc测试中, Spring容器不会初始化@Service注解的类
perform完成一次MVC调用
4.MVC模拟请求
模拟一个get请求
mockMvc.perform(get("/user/getCredit/{id}",userId))
模拟一个post请求
mockMvc.perform(post("/user/getCredit/{id}",userId))
模拟请求参数
mockMvc.perform(get("/user/test").param("message", "hello,world"))
5.比较MVC请求返回结果
@Test public void now() throws Exception { mockMvc.perform(get("/hello")) .andExpect(view().name("hello")) .andExpect(model().size(2)) .andExpect(model().attribute("name", "pangyazhou")) .andExpect(model().attributeExists("age")) .andExpect(redirectedUrl("/login.html")) .andExpect(forwardedUrl("/login.html")); }
6.Json比较
@RunWith(SpringRunner.class) @WebMvcTest(JsonController.class) public class JsonControllerTest { @Autowired private MockMvc mvc; @Test public void getUser() throws Exception { int id = 10; String name = "pangyazhou"; String path = "$.success"; mvc.perform(get("/json/user/{id}/{name}", id, name)) .andExpect(jsonPath(path).value(true)) .andExpect(jsonPath("$.store.*").exists()) .andExpect(jsonPath("$..book.length()").value(2)); } }
三.Mockito使用
模拟任何类和接口, 模拟方法调用,模拟异常抛出
1.模拟对象
@RunWith(MockitoJUnitRunner.class) public class CreditSystemServiceTest { @Test public void getUserCredit() { int userId = 10; int expectedCredit = 1000; CreditSystemService creditSystemService = mock(CreditSystemService.class); when(creditSystemService.getUserCredit(anyInt())).thenReturn(expectedCredit); int credit = creditSystemService.getUserCredit(userId); assertEquals(expectedCredit, credit); } }
2.模拟参数
@Test public void getUserCredit() { int userId = 10; int expectedCredit = 1000; CreditSystemService creditSystemService = mock(CreditSystemService.class); when(creditSystemService.getUserCredit(anyInt())).thenReturn(expectedCredit); when(creditSystemService.getUserCredit(any(int.class))).thenReturn(expectedCredit); when(creditSystemService.getUserCredit(eq(userId))).thenReturn(expectedCredit); int credit = creditSystemService.getUserCredit(userId); credit = creditSystemService.getUserCredit(userId); assertEquals(expectedCredit, credit); verify(creditSystemService, times(2)).getUserCredit(eq(userId)); }