zoukankan      html  css  js  c++  java
  • 单元测试之PowerMock

    PowerMock是一个Java模拟框架,用于解决测试问题。

    举个例子,你在使用Junit进行单元测试时,并不想让测试数据进入数据库,怎么办?这个时候就可以使用PowerMock,拦截数据库操作,并模拟返回参数。

    Quick Start

    1.引入maven依赖

    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito2</artifactId>
        <version>2.0.4</version>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4</artifactId>
        <version>2.0.4</version>
        <scope>test</scope>
    </dependency>
    
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-core</artifactId>
        <version>2.0.4</version>
        <scope>test</scope>
    </dependency>
    

    2.一个简单的例子

    • @RunWith告诉JUnit使用PowerMockRunner进行测试
    • @PrepareForTest所有需要测试的类列在此处,适用于模拟final类或有final, private, static, native方法的类,,例如:@PrepareForTest({RandomUtil.class})
    • @PowerMockIgnore为了解决使用powermock后,提示classloader错误,例如:@PowerMockIgnore("javax.management.*")
    • @InjectMocks自动将@Mock注解的对象注入进来@InjectMocks注释的对象
    • @Mock声明对象是一个Mock对象,也可以使用PowerMockito.mock(UserService.class),但无法被自动注入。
    /**
     * PowerMockTests
     *
     * @author kancy
     * @date 2020/11/1 22:26
     */
    @RunWith(PowerMockRunner.class)
    @PrepareForTest({UserThreadLocalUtil.class})
    @PowerMockIgnore
    public class PowerMockTests {
    
        @InjectMocks
        private UserController userController;
    
        @Mock
        private UserService userService;
    
        @Test
        public void queryUserTest(){
    
            Long userId = 1L;
    
            User user = new User();
    
            // mock , 当调用userService.findById()方法时,返回user对象
            PowerMockito.when(userService).findById(any()).thenReturn(user);
    
            User queryUser = userController.queryUser(userId);
    
            Assert.assertEquals(queryUser, user);
        }
    }
    

    3.Mock静态方法

    mock静态方法,有两个前提。

    1. @PrepareForTest声明该方法所在的该类
    2. PowerMockito.mockStatic(UserThreadLocalUtil.class)声明
    /**
     * PowerMockTests
     *
     * @author kancy
     * @date 2020/11/1 22:26
     */
    @RunWith(PowerMockRunner.class)
    @PrepareForTest({UserThreadLocalUtil.class})
    public class UserThreadLocalUtilTests {
    
        @Test
        public void getUserIdTest(){
            
            Long userId = 1L;
    
            PowerMockito.mockStatic(UserThreadLocalUtil.class);
            PowerMockito.when(UserThreadLocalUtil.getUserId()).thenReturn(userId);
    
            Assert.assertEquals(userId, UserThreadLocalUtil.getUserId());
        }
    }
    

    Spy功能

    Spy很少用,但是也极其强大,有的时候,例如有两个静态方法或者实例,如果我只想mock其中之一,这个时候Spy就该上场了。它的强大之处就在于可以部分mock。

    UserService userService = PowerMockito.spy(new UserService());
    PowerMockito.doNothing().when(userService).printUser1(any());
    
    // printUser1被mock了,所以不会打印User。
    userService.printUser1(new User());
    
    // 如果是spy,printUser2没有mock了,则会按照真实的方法执行会打印User,使用mock则会被拦截。
    userService.printUser2(new User());
    

    其他案例

    1.mock无返回值的方法

    • PowerMockito.doNothing().when(userService).deleteUser(any());

    2.mock有返回值的方法

    • PowerMockito.doReturn(new User()).when(userService.queryUser(eq(1L)));
    • PowerMockito.when(userService.queryUser(anyLong())).thenReturn(new User());

    3.mock方法执行异常

    • PowerMockito.doThrow(new RuntimeException()).when(userService.queryUser(any()));
    • PowerMockito.when(userService.queryUser(any())).thenThrow(new RuntimeException());

    4.mock构造方法

    • PowerMockito.whenNew(File.class).withAnyArguments().thenReturn(new File("/test"));
    • PowerMockito.whenNew(UserService.class).withNoArguments().thenReturn(new UserService());

    5.mock静态方法

    PowerMockito.mockStatic(StringUtils.class);
    PowerMockito.doReturn(true).when(StringUtils.hasText(anyString()));
    

    6.mock私有方法

    • PowerMockito.doNothing().when(userService, "printUser", any(User.class));
  • 相关阅读:
    虚拟内存思想
    虚拟内存映射 段分割 vm_area_struct
    进程、内存的理想与现实 VS 虚拟内存
    进程地址空间
    MMU CPU及思想
    链接器和加载器 好书
    编译器 链接器 加载器
    链接器简介
    C编译器、链接器、加载器详解
    静态库是.o文件的集合与弱符号
  • 原文地址:https://www.cnblogs.com/kancy/p/13912443.html
Copyright © 2011-2022 走看看