一直想系统的学习一下单元测试,来搞一把,学习资料。
单元测试实战
虽然有点唠叨,但是前面课程真的是经验之谈
PowerMock实战
单元测试痛点
是否需要启动Spring
单元测试启动的是junit容器,把Spring注入进来的,如果验证接口实现增删改查,那么是需要启动Spring的,但是集成测试也会计算,建议关键算法实现单元测试。
追求速度时,也可以mock Mapper,去掉对外的数据库等依赖。
单元测试框架选型
Junit4
BeforeClass:加载这个类之前需要准备的
Before:创建对象之前需要准备的
Test:标注测试方法
After:数据库等是放
AfterClass:
RunWith:加载哪些
单元测试实战
1. Junit4
Junit4不用加任何的注解,直接就可以开始单元测试
被测公有方法:
public String sayHello(){
return "hello";
}
测试方法,仅使用@Test标注为此方法为测试方法即可,对象为new的对象,Assert尽量使用Junit的Assert
@Test
public void testSayHello(){
UserService userService = new UserService();
Assert.assertEquals("hello",userService.sayHello());
}
被测私有方法
可以使用反射,但是代码量和学习成本较高,建议使用PowerMock
private String sayPrivateWorld(){
return "world";
}
单测:
注 Whitebox.invokeMethod可以调用私有方法
@Test
public void testSayWorld() throws Exception {
UserService userService = new UserService();
String result = Whitebox.invokeMethod(userService,"sayPrivateWorld");
Assert.assertEquals("world",result);
}
调用静态方法:
private static String sayJunit() {
return "junit";
}
单测方法:
Whitebox.invokeMethod(UserService.class,“sayJunit”)即可
@Test
public void testSayJunit() throws Exception {
String result = Whitebox.invokeMethod(UserService.class,"sayJunit");
Assert.assertEquals("junit",result);
}
调用System函数的方法
private static long sayTime(){
long time = System.currentTimeMillis();
return time + 1;
}
使用大神的方法修复了:
@RunWith(PowerMockRunner.class)
@PrepareForTest(UserService.class)
public class UserServiceTest {
@Before
public void setup() {
PowerMockito.mockStatic(System.class);
}
@Test
public void testSayTime() throws Exception {
PowerMockito.when(System.currentTimeMillis()).thenReturn(1000L);
long result = Whitebox.invokeMethod(UserService.class, "sayTime");
Assert.assertEquals(1001L, result);
}
}
powerMock实现调用shell
被测代码
public String exec() throws Exception {
Process proc = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", "ls /root/"});
InputStream stdin = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(stdin);
BufferedReader br = new BufferedReader(isr);
String line = null;
String result = "";
while ((line = br.readLine()) != null) {
result = result + line;
System.out.println(line);
System.out.println("");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
}
return result;
}
测试代码:
@RunWith(PowerMockRunner.class)
@PrepareForTest(UserService.class)
public class UserServiceTest {
@Before
public void setup() {
PowerMockito.mockStatic(System.class);
PowerMockito.mockStatic(Runtime.class);
}
@Test
public void testExec() throws Exception {
UserService userService = new UserService();
Process process = PowerMockito.mock(Process.class);
PowerMockito.when(Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", "ls /root/"})).thenReturn(process);
PowerMockito.when(process.getInputStream()).thenReturn(new ByteArrayInputStream("helloworld".getBytes()));
String result = userService.exec();
System.out.println(result);
}
}
powerMock与SpringBoot
上面的案例都无法使用AutoWired,只能直接mock对象