Java Unit Test - Mockito mock静态方法


一、当需要mock静态方法的时候,必须加注解@PrepareForTest和@RunWith。注解@PrepareForTest里写的类是静态方法所在的类。

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;

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.eq;

@RunWith(PowerMockRunner.class)
@PrepareForTest(String.class)
public class MockPrepareForTest {

    @Test
    public void testStaticMathod () {
        TestString testString = new TestString();

        PowerMockito.mockStatic(String.class);
        PowerMockito.when(String.valueOf(eq(100l))).thenReturn("TEST");

        String result = testString.getTestString(100l);

        assertEquals("TEST", result);
    }

    class TestString {

        public String getTestString(long number) {
            return String.valueOf(number);

        }
    }
}

    以上模拟静态方法的方式仅适用于JDK8 以下的版本,如果你想在JDK8+的版本模拟静态方法,可以用以下的方式。

 

 

二、使用最新版本的 Mockito 模拟静态方,我们测试的重点将是一个简单的静态实用程序类:

public class StaticUtils {

    private StaticUtils() {}

    public static List<Integer> range(int start, int end) {
        return IntStream.range(start, end)
          .boxed()
          .collect(Collectors.toList());
    }

    public static String name() {
        return "Baeldung";
    }
}

 

  1. 添加依赖
    让我们开始将mockito-inline依赖项添加到我们的pom.xml
    <dependency>
        <groupId>org.mockito</groupId>
        <artifactId>mockito-inline</artifactId>
        <version>3.8.0</version>
        <scope>test</scope>
    </dependency>

     

  2. 模拟无参静态方法
    @Test
    void givenStaticMethodWithNoArgs_whenMocked_thenReturnsMockSuccessfully() {
        assertThat(StaticUtils.name()).isEqualTo("Baeldung");
    
        try (MockedStatic<StaticUtils> utilities = Mockito.mockStatic(StaticUtils.class)) {
            utilities.when(StaticUtils::name).thenReturn("Eugen");
            assertThat(StaticUtils.name()).isEqualTo("Eugen");
        }
    
        assertThat(StaticUtils.name()).isEqualTo("Baeldung");
    }

    如前所述,从 Mockito 3.4.0 开始,我们可以使用Mockito.mockStatic( Class<T> classToMock )方法来模拟对静态方法调用的调用。此方法为我们的类型返回一个MockedStatic对象,它是一个作用域模拟对象。

    因此,在我们上面的单元测试中,utilities变量表示具有线程局部显式作用域的模拟。需要注意的是,作用域模拟必须由激活模拟的实体关闭。这就是为什么我们在try-with-resources构造中定义我们的模拟,以便当我们完成我们的作用域块时模拟会自动关闭。

    这是一个特别好的功能,因为它确保我们的静态模拟保持临时。正如我们所知,如果我们在测试运行期间使用静态方法调用,由于运行测试的并发和顺序特性,这可能会对我们的测试结果产生不利影响。

    最重要的是,另一个很好的副作用是我们的测试仍然会运行得非常快,因为 Mockito 不需要为每个测试替换类加载器。

  3. 用参数模拟静态方法

    现在让我们看看另一个常见的用例,当我们需要模拟一个有参数的方法时:

    @Test
    void givenStaticMethodWithArgs_whenMocked_thenReturnsMockSuccessfully() {
        assertThat(StaticUtils.range(2, 6)).containsExactly(2, 3, 4, 5);
    
        try (MockedStatic<StaticUtils> utilities = Mockito.mockStatic(StaticUtils.class)) {
            utilities.when(() -> StaticUtils.range(2, 6))
              .thenReturn(Arrays.asList(10, 11, 12));
    
            assertThat(StaticUtils.range(2, 6)).containsExactly(10, 11, 12);
        }
    
        assertThat(StaticUtils.range(2, 6)).containsExactly(2, 3, 4, 5);
    }

    在这里,我们遵循相同的方法,但这次我们在我们的when子句中使用lambda 表达式,我们在其中指定方法以及我们想要模拟的任何参数。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM