当前位置: 首页 > 知识库问答 >
问题:

每个@InjectMocks调用都不考虑PowerMock静态方法模拟

尉迟轶
2023-03-14

我想编写一些使用JUnit4.12、Mockito1.9.5和PowerMock1.6.1的单元测试。这个类有一些用@mock注释的字段,还有一些用@injectmocks注释的字段。用@InjectMocks注释的属性在某个点到达一个父构造函数,该父构造函数包含一些静态方法调用,应该用PowerMock来模拟。问题是第一个测试是无缝工作的,而第二个测试似乎根本没有嘲弄静态方法。

java prettyprint-override">@RunWith(PowerMockRunner.class)
@PrepareForTest({ StaticClass.class })
public class TestClass {
  @Mock
  private SomeClass attribute1;
  @InjectMocks
  private SomeOtherClass attribute2;

  @BeforeClass
  public static void setUp() {
    PowerMockito.mockStatic(StaticClass.class);

 when(StaticClass.staticMethod(any(), any()).thenReturn(new SomeConcreteClass());
  }

  @Test
  public void test1() {
    assertEquals(attribute2.method1(), value1);
  }

  @Test
  public void test2() {
    assertEquals(attribute2.method2(), value2);
  }
}

public class SomeOtherClass {
  private SomeClass attribute;
  public SomeOtherClass() {
    SomeConcreteClass value = StaticClass.staticMethod(argument1, argument2);
    value.someOtherMethod();
  }
}

如前所述,第一个测试通过了,StaticClass.StaticMethod()被PowerMock模拟。第二个测试没有通过,当对value调用someOtherMethod时,它在行抛出NullPointerException(因为value=null,因为StaticClass.StaticMethod不再被PowerMock嘲弄)。

共有1个答案

郭元明
2023-03-14

正如(Mocking Behavious resets after each test with PowerMock)中所解释的,PowerMock在每次测试之前都会重置模拟。由于某种原因,它第一次工作-存在一个关于该问题的未解决的错误报告(https://github.com/PowerMock/PowerMock/issues/398)。

它的设计可能很糟糕,但可以通过以下方法来实现:
而不是依赖于注释,手动设置mocks。

private SomeClass attribute;
private SomeOtherClass testClass;

@Before
public void setUp() {
    PowerMockito.mockStatic(StaticClass.class);
    Mockito.when(StaticClass.staticMethod(anyString())).thenReturn(new SomeConcreteClass());

    attribute = Mockito.mock(SomeClass.class);      
    testClass = new SomeOtherClass();

    // assign mock manually
    testClass.attribute = attribute;
}

最好的方法是使用SomeOtherClass的构造函数提供属性
但是,由于您似乎使用了空的构造函数,您将不得不从外部设置值。
如果Attribute实例不可访问,您可能会被迫使用反射。

更简单的方法是重构SomeOtherClass的构造函数,使其不在内部使用静态方法。相反,将someConcreteclass作为参数传递给构造函数才是可行的方法。

有些人甚至说构造函数内部不应该有任何逻辑。

 类似资料:
  • Powermock为什么不模拟静态方法调用,而是在然后()语句中调用初始方法? 在这种情况下,我有一系列方法调用: TestClass方法-调用- Class4方法尝试查找上下文中不存在且挂起的对象,因此我尝试使用Powermock模拟公共静态Class3方法。 所有的类和方法都是非最终的。我使用TestNg。我的测试方法有一个@准备测试我尝试了以下方法来模拟方法调用: 或而不是当-然后返回: 或

  • 我正在尝试使用JUnit、Mockito和PowerMock验证对的调用。 下面是我的测试用例: 下面是测试中的代码: 非常有趣的是,这段代码失败时出现:

  • 我正在设置模拟类的静态方法。我必须在一个带有注释的JUnit安装方法之前的JUnit中进行此操作。 我的目标是将类设置为调用真正的方法,但我显式模拟的方法除外。 基本上: 我遇到的问题是,如果提供了值,则在中,方法不幸地抛出。 因此,我不能简单地将调用real方法作为默认答案,如下所示: 在模拟了我感兴趣的方法的结果之后,我需要将默认答案设置为在所有其他静态方法上调用real方法。 这可能吗?

  • 我试图用PowerMock在Mockito上模拟一个静态void方法,但它并不是那么好用。 我的示例代码: EvilBrother.java 我的问题是,嵌套类按照预期的方式使用@PrepareForTest和PowerMockito.MockStatic组合进行了模拟,但是如果类在自己的类文件中,这些语句就不起作用了。 如何修复这个测试? 与 尽管执行了assert.fail,但可以通过Powe

  • 我想知道是否有一种方法来验证和调用一个模拟,该模拟是为一个私有静态方法创建的,该私有静态方法是从一个被测试的公共静态方法调用的。 下面是我正在测试的公共静态方法 我已经使用powermokito对私有静态方法进行了如下嘲弄: