一直想系统的学习一下单元测试,来搞一把,学习资料。
 单元测试实战
 虽然有点唠叨,但是前面课程真的是经验之谈
 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对象










