我正在实现一个类X,它有一个方法xyz(),它使用类A的静态方法abc()。这个静态方法abc()接受同一个类的另一个静态方法的返回值,它接受2个参数。一个是HTTPServletRequest对象,另一个是一个枚举的值。我想测试我的类X的方法xyz()的功能,为此我想到使用PowerMockRunner来模拟类A的xyz()方法。但是我在这里面临问题而不能这样做。 ''除了'子句不起作用,因此它没有返回值,我希望它返回正常测试继续。请指教。
@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);
}
}
答案 0 :(得分:1)
虽然你在询问如何模拟静态方法,但我会给你一个真实问题的答案。我想,你实际上是XY problem。
因此,在测试您的某个方法时,您有机会大大改进您的测试代码。你显然已经意识到静态方法可能是测试的痛苦。怎么办?
简单回答:通过界面表达所需的功能!
我将给出一个Java运行时库中的一些静态方法的示例。您可以轻松地将机制传输到您的代码。让我们使用静态的Math.random()
方法。应测试的方法:
final class MyClass {
double myMethod(double multiplier) {
double result = Math.random() * multiplier;
return result;
}
}
对随机功能的调用实际上是此代码所属类的依赖项。所以我们首先创建一个包含这个功能的接口:
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
来实例化。无参数构造函数是提供默认构造函数的简单方法。它可以省略,但是代码的其他部分也必须改变。
现在测试变得非常简单。您只需创建一个用于实例化该类的接口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可以轻松完成测试实现的创建(我也是出于这些目的)。但是......这个场景不需要模拟框架。事实上,这不是 mocking ,它是简单的 stubbing 。