Java测试之Mockito与PowerMock(二)

引言

上节在使用mock测试时,遇到final、private、static方法,但Mockito不支持这些方法的测试,这时我们需引入PowerMock

导包

想要使用PowerMock,就得先导入其jar包

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <mockito.version>2.8.9</mockito.version>
        <powermock.version>1.7.4</powermock.version>
    </properties>


       <!-- 此处只展示测试的相关依赖 -->
       <!-- Test -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
       
        <!-- powermock 的依赖 -->
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>${powermock.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito2</artifactId>
            <version>${powermock.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>${mockito.version}</version>
            <scope>test</scope>
        </dependency>

如何使用PowerMock测试静态方法

 //类上面引入注解,使用PowerMockRunner.class
@RunWith(PowerMockRunner.class)
//使用PrepareForTest注解代替mock注解来模拟静态类
@PrepareForTest({HttpUtils.class})
//排除一些SSL认证异常
@PowerMockIgnore( {"javax.management.*", "javax.net.ssl.*"})
public class PowerMockTest {

    @InjectMocks
    SynServiceImpl synService;

    private static Student student;

    @BeforeClass
    public static void create() {

        student = new Student ();
        student.setName("xiaoming");
        student.setAge("22");
      
    }

    @Before
    public void init(){
        //PowerMockito.mockStatic(HttpUtils.class);
     
     }

    @Test
    public void testDoPost() {
       String respon = "{" +
                "\"result\": \"ok\", " +
                "\"req_method\": \"student_synadd\", " +
                "\"data\": [{" +
                "\"status\": \"ok\"" +
                "}], " +
                "\"system_time\": \"1556436736.341\"} ";
                
       //设置静态方法的类(使用@before统一设置)
       PowerMockito.mockStatic(HttpUtils.class);
       //指定需要测试静态方法的行为
       PowerMockito.when(HttpUtils.doPost(Mockito.anyString(),Mockito.anyMap())).thenReturn(respon);
       synService.addStudent(student);

   }



}

其他同mockito,但引入powerMockito后,之前的测试类出现了一点奇葩问题

遇到的问题:

org.mockito.exceptions.misusing.UnnecessaryStubbingException:
Unnecessary stubbings detected in test class: Test
Clean & maintainable test code requires zero unnecessary code.
Following stubbings are unnecessary (click to navigate to relevant line of code):

  1. -> at service.Test.testDoSearch(Test.java:72)
    Please remove unnecessary stubbings or use ‘silent’ option. More info: javadoc for UnnecessaryStubbingException class.

业务表现:单个方法测试正常,一个类运行测试出现UnnecessaryStubbingException,说是存在未使用的存根,为了代码整洁请去掉这些存根或是使用silent策略
若注释掉这些未使用的存根,单个方法运行会出现空指针异常,也就是说一个方法里有多个分支,进去这些分支,需要模拟不同的临界值,在整体运行时可能跳过某些细节、忽略掉某些分支,导致出现存根未使用的情况。

解决方法:

  1. silent策略
    @RunWith(MockitoJUnitRunner.Silent.class) 替换@RunWith(MockitoJUnitRunner.class)。
    自Mockito 2.1.0起新增功能,将检测测试代码中未使用的存根,来保持代码的清洁,通过注解关闭此功能,但是 不生效,最终发现是jar包版本有冲突导致的,但是不推荐使用这个方法,这只是隐藏问题并没有解决问题。

  2. 分支独立
    将每个分支独立一个测试方法,这样代码有点臃肿,但是在单个运行时没问题,整体运行时有空指针异常,通过debug调试,发现部分值在测试时发现了改变,因此可在提示的空指针处再次进行赋值即可避免此问题。

参考解决方法
相关译文

未完待续。。。。。。。。。。

Spring Boot是一个非常流行的Java框架,MockitoPowerMock是两个常用的Java测试框架。集成MockitoPowerMock可以帮助我们更好地进行单元测试和集成测试。下面是Spring Boot集成MockitoPowerMock的步骤: ### 1. 添加依赖 在pom.xml中添加以下依赖: ``` <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>3.10.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito2</artifactId> <version>2.0.9</version> <scope>test</scope> </dependency> ``` ### 2. 编写测试类 编写需要测试的类和测试类,例如: ``` @Service public class UserService { @Autowired private UserRepository userRepository; public User getUserById(Long id) { return userRepository.findById(id).orElse(null); } } @RunWith(PowerMockRunner.class) @PrepareForTest(UserRepository.class) public class UserServiceTest { @InjectMocks private UserService userService; @Mock private UserRepository userRepository; @Test public void testGetUserById() { Long id = 1L; User user = new User(); user.setId(id); user.setName("MockitoTest"); Mockito.when(userRepository.findById(id)).thenReturn(Optional.of(user)); User result = userService.getUserById(id); Assert.assertEquals(result.getName(), "MockitoTest"); } } ``` ### 3. 运行测试 运行测试类,如果测试通过,则说明MockitoPowerMock已经成功集成到Spring Boot中。 以上是Spring Boot集成MockitoPowerMock的基本步骤。需要注意的是,MockitoPowerMock虽然可以帮助我们进行更好的测试,但是过度使用也会导致测试变得复杂和难以维护,因此需要谨慎使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值