书接上回:
https://blog.youkuaiyun.com/qq_36110736/article/details/107897223
在单元测试中非常有可能会遇到一些静态方法,由于静态方法无法被实例对象所调用所以我们通过 mock 的方式也无法直接测试静态方法,此时就需要 PowerMock 的方式来测试静态方法。
第一步 添加依赖:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.3</version>
<scope>test</scope>
</dependency>
准备工作,在被测试类中添加一个静态方法
public static UserLogin loginStatic(){
return null;
}
第二步:
- 修改 @RunWith(PowerMockRunner.class)
- 添加@PrepareForTest({StaticTest.class})
- 使用PowerMockito.mockStatic(StaticTest.class);
package com.example.demo.staticmethod;
import com.example.demo.dao.LoginDao;
import com.example.demo.po.UserLogin;
import jdk.internal.dynalink.beans.StaticClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({LoginDao.class})
public class StaticTest {
private UserLogin userLogin = new UserLogin();
@Test
public void staticTest(){
PowerMockito.mockStatic(LoginDao.class);
PowerMockito.when(LoginDao.loginStatic()).thenReturn(userLogin);
System.out.println("==================");
System.out.println(LoginDao.loginStatic());
System.out.println("==================");
}
}
测试结果:
注意:
在初次测试中抛出了如下异常
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.
一般来说这是由于依赖的版本冲突导致的,同时由于我的项目时Spring Boot项目,已经默认导入了spring-boot-starter-test模块,里面也集成了JUnit 和Mockito,将他注释掉,其他测试类会报错,重新引入就可以。
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-test</artifactId>-->
<!-- <scope>test</scope>-->
<!-- <exclusions>-->
<!-- <exclusion>-->
<!-- <groupId>org.junit.vintage</groupId>-->
<!-- <artifactId>junit-vintage-engine</artifactId>-->
<!-- </exclusion>-->
<!-- </exclusions>-->
<!-- </dependency>-->
参考:
https://blog.youkuaiyun.com/dengqunhua/article/details/84901914
https://www.it1352.com/984614.html
https://segmentfault.com/a/1190000019000146?utm_source=tag-newest
https://cloud.tencent.com/developer/ask/176584/answer/280595