mockito Junit5模拟静态方法

gj3fmq9x  于 2023-01-17  发布在  其他
关注(0)|答案(5)|浏览(325)

我想在JUnit 5中模拟一个静态方法。但不幸的是,JUnit 5不支持Mockito。除了恢复到JUnit 4之外,还有其他方法可以实现相同的效果吗?

r1zhe5dt

r1zhe5dt1#

从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"));
    }
}
axr492tv

axr492tv2#

简短的回答是否定的,因为Mockito团队已经完成了他们的work,正在等待JUnit团队提供extension,并且在这里讨论了很多。
通过一些开销,您可以:由于JUnit 5支持运行遗留的JUnit 4,因此您可以使用Mockito。因此,您可以在Junit4中为以下情况创建测试:
使用gradlemvn进行迁移设置的示例项目。从那里我将使用PowerMock 2.0 beta和Mockito 2。

vnjpjtjt

vnjpjtjt3#

Mockito目前不提供静态方法mocking的原因是因为人们普遍认为静态方法不需要被mocking。
但是,Mockito here有一个讨论该问题的开放项目。
虽然这并没有回答你的问题,但总的来说,它告诉你为什么你根本不需要这个功能,或者允许你加入讨论,提出你的想法。

7rfyedvj

7rfyedvj4#

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

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>3.6.28</version>
    <scope>test</scope>
</dependency>

1.在我的例子中,我必须测试异常抛出URLEncoder类的静态方法encode()的场景,因此

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"));
}
y53ybaqx

y53ybaqx5#

我们可以使用JMockit模拟静态方法。
JMockit用于模拟测试边界之外的外部依赖,类似于Mockito和其他类似的模拟库,JMockit最重要的特性是允许我们模拟任何东西,甚至是其他库难以模拟的东西,如构造函数、静态方法和最终方法,甚至允许模拟成员字段和初始化块。

按照以下步骤启用JMockit:

  1. JMockit工件位于中央Maven存储库中,请在pom.xml中添加JMockit依赖项
<!-- https://mvnrepository.com/artifact/org.jmockit/jmockit -->
    <dependency>
        <groupId>org.jmockit</groupId>
        <artifactId>jmockit</artifactId>
        <version>1.49</version>
        <scope>test</scope>
    </dependency>

1.在TestClass中模拟Class方法:

public class TestClass{
 @Test
 public void testMethod() {
     new MockUp<ClassName>(){
         @Mock
         //mock  the method here
     };
 }

}
请按照教程了解有关如何使用JMockit的更多信息。

相关问题