使用Mockito mock一个静态方法

使用Mockito mock一个静态方法

在3.4.0之前,我们是不能使用Mockito来mock一个静态方法的,而必须使用PowerMockito;但是在之后的版本中已经支持了通过Mockito直接来mock。

下面我们就一步一步来看怎么去使用。

1.一个建单的静态工具类

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

为了演示,我们提供了一个无参数的返回值为String的方法和一个带参数并返回List的方法。

2.Maven依赖

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

在本例中,我们使用了mockito-inline版本号为3.8.0的包,当前最新的版本为4.5.1

3.Mock无参数静态方法
下面我们来看看如何Mock无参数的方法-name。

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

首先我们需要把我们的mockStatic写到try-with-resources代码块中,以确保我们在使用完mock的静态方法后能够及时释放;同时我们会在测试用例的前后分别校验name方法的返回值,确保前后都没有被mock,返回的真实值,符合我们的预期;但是该方法并不一定好实现,如果返回的结果可能会变化不定的话。

4.Mock带参数的静态方法

@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);
}

格式为:

MockedStatic<T> utilities = Mockito.mockStatic(T.class)

utilities.when(() -> T.function(arg1, arg2)) .thenReturn(result);