我需要测试 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());
}
}
一般来说(并非总是如此),需要模拟
static
方法会在代码中标记出糟糕的设计。
如果您的代码使用
static
方法,则意味着无论用法如何,它都需要使用该方法。但是,如果您需要模拟它进行测试,那么也许您实际上并不需要静态方法,而是需要一个根据上下文返回不同内容的interface
。
有时,我们根本没有选择(例如,我们无法控制正在测试的代码,并且该代码使用我们需要模拟的
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);