Junit5模拟静态方法

Pri*_*iya 5 unit-testing mockito powermock junit5

我想在junit5中模拟静态方法。但不幸的是,Junit5不支持Powermockito。除了恢复到Junit4之外,还有其他方法可以实现相同的目的吗

ang*_*era 26

从 Mockito 3.4.0(2020 年 7 月 10 日)开始,即使在JUnit 5中也可以开箱即用地模拟静态方法,无需任何扩展。

在文档中,您可以找到一个示例:https : //javadoc.io/static/org.mockito/mockito-core/3.4.6/org/mockito/Mockito.html#static_mocks

重要提示:您需要使用inline mock maker。所以要使用的依赖不是核心的:

        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-inline</artifactId>
            <version>3.4.6</version>
            <scope>test</scope>
        </dependency>
Run Code Online (Sandbox Code Playgroud)

示例:被测类:

package teststatics;

public class FooWithStatics {
    public static Long noParameters() {
        return System.currentTimeMillis();
    }
    public static String oneParameter(String param1) {
        return param1.toUpperCase();
    }
}
Run Code Online (Sandbox Code Playgroud)

测试类:

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"));
    }
}
Run Code Online (Sandbox Code Playgroud)


AR1*_*AR1 8

Mockito 目前不提供静态方法模拟的原因是因为人们普遍认为静态方法不需要被模拟。然而,有对一个的Mockito开放项目在这里,讨论的问题。虽然这不能回答您的问题,但通常它会告诉您为什么根本不需要该功能或将允许您加入与您的想法的对话。


小智 5

简短的回答是不,因为PowerMockito团队已经完成了他们的工作,正在等待JUnit团队进行扩展并在这里进行了大量讨论。

有了一些开销,您可以:由于JUnit5提供了运行旧版JUnit4的支持,因此您可以在其中使用PowerMockito。因此,您可以在Junit4中针对以下情况创建测试:使用gradlemvn进行迁移设置的示例项目。从那里开始,我在Mockito2中使用PowerMock 2.0 beta


小智 5

  1. 确保mockito-inline您的 POM 文件具有依赖关系

    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-inline</artifactId>
        <version>3.6.28</version>
        <scope>test</scope>
    </dependency>
    
    Run Code Online (Sandbox Code Playgroud)
  2. 就我而言,我必须测试抛出异常的类静态方法encode()的场景URLEncoder,因此为此

    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"));
    }
    
    Run Code Online (Sandbox Code Playgroud)