从Mockito 3.4.0(2020-07-10)开始,即使在JUnit 5中也可以直接模拟静态方法,无需使用任何扩展。
在文档中,你可以找到一个例子:48.模拟静态方法(自3.4.0起)
重要提示:需要使用 inline mock maker 。 因此,需要使用的依赖项不是核心依赖项:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.4.6</version>
<scope>test</scope>
</dependency>
例子: 测试的类:
package teststatics;
public class FooWithStatics {
public static Long noParameters() {
return System.currentTimeMillis();
}
public static String oneParameter(String param1) {
return param1.toUpperCase();
}
}
测试类:
package teststatics;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
public class FooWithStaticsTest {
@Test
void testStatic() {
// Before mock scope, usual behavior.
assertNotEquals(0L, FooWithStatics.noParameters());
assertNotEquals("yyy", FooWithStatics.oneParameter("xxx"));
// Mock scope
try (MockedStatic mocked = mockStatic(FooWithStatics.class)) {
// Mocking
mocked.when(FooWithStatics::noParameters).thenReturn(0L);
mocked.when(() -> FooWithStatics.oneParameter("xxx")).thenReturn("yyy");
// Mocked behavior
assertEquals(0L, FooWithStatics.noParameters());
assertEquals("yyy", FooWithStatics.oneParameter("xxx"));
// Verifying mocks.
mocked.verify(times(1), FooWithStatics::noParameters);
mocked.verify(times(1), () -> FooWithStatics.oneParameter("xxx"));
}
// After mock scope returns to usual behavior.
assertNotEquals(0L, FooWithStatics.noParameters());
assertNotEquals("yyy", FooWithStatics.oneParameter("xxx"));
}
}
mocked.verify(times(1), () -> FooWithStatics.oneParameter("xxx"))
不再有效,而是必须改为mocked.verify(() -> FooWithStatics.oneParameter("xxx"), times(1))
。 - undefined简短的回答是不可以,因为Mockito团队已经完成了他们的工作,正在等待JUnit团队提供一个扩展,并在这里进行了大量讨论。
但是,您可以通过一些额外的步骤来实现:由于JUnit 5支持运行传统的JUnit 4版本,因此您可以在JUnit 4中使用Mockito来创建测试用例,从而实现对这些情况的测试:
这里有一个迁移设置的示例项目,使用Gradle和Mvn。我使用了PowerMock 2.0 beta和Mockito 2。
Make sure to have mockito-inline
dependency in your POM file
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.6.28</version>
<scope>test</scope>
</dependency>
In my case I had to test scenario where exception thrown static method encode()
of URLEncoder
Class, so for that
try (MockedStatic theMock = mockStatic(URLEncoder.class)) {
theMock.when(() -> URLEncoder.encode("Test/11", StandardCharsets.UTF_8.toString()))
.thenThrow(UnsupportedEncodingException.class);
when(restClient.retrieveByName("Test%2F11")).thenReturn(null);
Assertions.assertThrows(ResponseStatusException.class, ()->service.retrieveByName("Test/11"));
}
mockito-inline
组件来模拟静态方法。
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
</exclusion>
<exclusion>
<artifactId>mockito-junit-jupiter</artifactId>
<groupId>org.mockito</groupId>
</exclusion>
</exclusions>
</dependency>
class FilesUtility{
public static boolean something(String x , String y){
return true;
}
}
@Test
void testStaticMethod() {
try (MockedStatic<? extends FilesUtility> mocked =
mockStatic(FilesUtility.class, CALLS_REAL_METHODS)) {
mocked
when(() -> FilesUtility.something(any(), any()))
.thenReturn(false);
}
}
CALLS_REAL_METHODS
来提供一个答案。mockStatic(FilesUtility.class, CALLS_REAL_METHODS)
CALLS_REAL_METHODS
参数来保持它们的默认行为。这相当于对该类进行监视。我们可以使用JMockit来模拟静态方法。
JMockit用于模拟测试边界之外的外部依赖项,类似于Mockito和其他模拟库。 JMockit最重要的特点是它让我们可以模拟任何东西,即使是其他库难以模拟的东西,如构造函数、静态和final方法。它甚至允许模拟成员变量和初始化块。
按照以下步骤启用JMockit:
<!-- https://mvnrepository.com/artifact/org.jmockit/jmockit -->
<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>1.49</version>
<scope>test</scope>
</dependency>
在TestClass中模拟类方法:
public class TestClass{
@Test
public void testMethod() {
new MockUp<ClassName>(){
@Mock
//在此处进行方法模拟
};
}
}
请跟随tutorial了解更多关于如何使用JMockit的内容。