Mockito mock 静态方法

Mockito mock static method

提问人:Poli 提问时间:11/10/2023 更新时间:11/11/2023 访问量:32

问:

我需要在类 MyClass 中测试方法 myMethod,为此,我需要拦截 nextInt 调用以返回指定值。我该怎么做?

import static org.apache.commons.lang3.RandomUtils;

public class MyClass {
    public int myMethod() {
        int a = nextInt();
        return a;
    }
}

这就是我尝试过的,我想要一个使用 mockito 或 powerMock 以这种方式的解决方案。

import org.apache.commons.lang3.RandomUtils;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import tech.delvi.recipeBusinessLogic.MyClass;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;

public class Prova {
    public static void main(String[] args) {
        test();
    }

    public static void test() {
        MockedStatic<RandomUtils> randomUtilsMockedStatic = Mockito.mockStatic(RandomUtils.class);
        randomUtilsMockedStatic.when(() -> RandomUtils.nextInt()).thenReturn(1);

        MyClass myClass = mock(MyClass.class);
        assertEquals(1, myClass.myMethod());
    }
}
java 测试 mockito powermockito

评论

2赞 tgdavies 11/10/2023
您正在测试.不要嘲笑它。MyClass

答:

1赞 Matteo NNZ 11/10/2023 #1

一般来说(并非一直如此),需要模拟方法会在代码中标记出一个糟糕的设计。static

如果您的代码使用某个方法,则意味着无论使用哪种方法,它都需要使用该方法。但是,如果您需要模拟它进行测试,那么也许您实际上并不需要静态方法,而是根据上下文返回不同内容的方法。staticinterface

有时,我们根本没有选择(例如,我们无法控制我们正在测试的代码,并且该代码正在使用我们需要模拟的方法),因此在这种情况下,使用模拟库来模拟它是剩下的唯一选择。但是,如果代码是你的(我认为是这种情况),那么我会以一种你可以更容易地嘲笑它的方式设计它。例如:static

public class MyClass {

    private final Supplier<Integer> intSupplier;

    public MyClass(Supplier<Integer> intSupplier) {
        this.intSupplier = intSupplier;
    }

    public int myMethod() {
        int a = intSupplier.get();
        return a;
    }
}

像这样,在生产中,您将执行:

MyClass myClass = new MyClass(() -> nextInt());

...在测试中,您可以执行以下操作:

MyClass myClass = new MyClass(() -> 1);

评论

0赞 Matteo NNZ 11/11/2023
@k314159我只是说“使用模拟库”,我会相应地更新