gpt4 book ai didi

java - 模拟类的静态函数

转载 作者:行者123 更新时间:2023-12-01 10:25:18 24 4
gpt4 key购买 nike

我正在实现一个类 X,它有一个方法 xyz(),该方法使用类 A 的静态方法 abc()。此静态方法 abc() 接受同一类的另一个静态方法的返回值,该方法接受 2 个参数。一个是 HTTPServletRequest 对象,另一个是一个枚举的值。我想测试 X 类的方法 xyz() 的功能,为此我想到使用 PowerMockRunner 来模拟 A 类的 xyz() 方法。但我在这里遇到问题,无法这样做。 “Except”子句不起作用,因此它没有返回我希望它返回以进行正常测试的值。请指教。

@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class DataProviderIntegrationTest {
@Mock
private HttpServletRequest request;

@TestSubject
X x= new X();

@Test
public void testXyz() throws Exception {

long customerId = 1;
expect(A.abc(A.pqr(request, B.CUSTOMER_ID.getAttributeValue()))).andReturn(customerId);
replayAll();
Output output = x.xyz();

Assert.assertNotNull(output);
}
}

最佳答案

虽然您询问如何模拟静态方法,但我会给您真正问题的答案。我想,你实际上有一个 XY problem .

因此,当您测试其中一种方法时,您有机会极大地改进您的测试代码。您显然已经意识到静态方法在测试中可能会很痛苦。该怎么办?

简单的答案:用界面表达所需的功能!

我将为您提供一个示例,其中包含 Java 运行时库中的一些静态方法。您可以轻松地将机制传输到您的代码中。让我们使用Math.random()方法是静态的。需要测试的方法:

final class MyClass {
double myMethod(double multiplier) {
double result = Math.random() * multiplier;
return result;
}
}

对随机功能的调用实际上是该代码所属类的依赖项。所以我们首先创建一个承载此功能的接口(interface):

interface Randomizer {
double random();
}

此外,我们为其创建了第一个实现:

final class DefaultRandomizer implements Randomizer {
@Override
public double random() {
return Math.random();
}
}

现在我们可以将类重写为:

final class MyClass {
private final Randomizer randomizer;

MyClass() {
this(new DefaultRandomizer());
}

MyClass(Randomizer randomizer) {
this.randomizer = Objects.requireNonNull(randomizer);
}

double myMethod(double multiplier) {
double result = randomizer.random() * multiplier;
return result;
}
}

正如您所看到的,该类的对象现在通过向它们提供所需的Randomizer来实例化。无参数构造函数是提供默认构造函数的一种简单方法。它可以被省略,但是代码的其他一些部分也必须更改。

现在测试变得非常容易。您只需创建接口(interface) Randomizer 的测试实现,用它来实例化该类。这样做可以让您完全控制测试方法的各个方面。

此类测试的示例:

public final class MyClassTest {

@Test
public void zeroRandomShouldReturnZeroForPositiveMultiplier() {
Randomizer zeroRandomizer = new Randomizer() {
@Override
public double random() {
return 0.0;
}
};
MyClass testObject = new MyClass(zeroRandomizer);
double multiplier = 42.0;
assertThat(testObject.myMethod(multiplier), is(0.0));
}

}

使用 Mockito 可以轻松完成测试实现的创建(我也出于这些目的这样做)。但是......这种情况不需要模拟框架。事实上,这不叫模拟,而是简单的 stub

关于java - 模拟类的静态函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35383113/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com