【问题标题】:How do mock a private or package protected class using PowerMockRunner?如何使用 PowerMockRunner 模拟私有或包保护类?
【发布时间】:2017-07-13 11:53:44
【问题描述】:

我想使用 PowerMock 覆盖包保护类中的一个方法,以进行我在 Android 项目上进行的一些测试。我相信这是执行此操作的正确方法,以便我可以代理我想代理调用的方法。

我的测试位于被测代码所在的包之外。

给定类:FooBar

package com.foo.bar
Class FooBar extends Object {
private void updateSomething(int Param1, String param2 ){
        //Do some work....
    }
}

我想要一个模拟的测试用例,以便我可以代理 updateSomething 方法。

我设想过这样的事情:

package com.example.test
@RunWith(PowerMockRunner.class)
public class TestClass {

    @PrepareForTest({com.foo.bar.FooBar.class}) //<---COMPLAINT IS HERE
    public void test001_doTest() {
    }
}

这里的问题是 IDE 抱怨 FooBar 类不是公共的。

Error:(209, 55) error: FooBar is not public in com.foo.bar; cannot be accessed from outside package.

我认为 PowerMock 能够免费克服这个问题。 任何建议将不胜感激。

顺便说一句:我意识到我可以在这里使用反射。但是在频繁调用此方法的情况下,我可能会设置测试,然后通过其他方式更改我通过模拟设置的值,从而导致测试错误地(并且间歇性地)失败。在这种情况下,我认为代理类和方法会更好。据说这就是 Mockito 和 PowerMock 的亮点?

【问题讨论】:

  • 如果您在测试代码中使用FooBar,那么代码必须在同一个包中。那么为什么要测试这段代码在不同的包中呢?
  • @MariuszMączkowski,被测代码作为 Java 库 (SDK) 交付并在测试应用程序中使用。这不是单元测试,而是更多的 SDK 测试,我们在更高级别测试功能,但仍需要控制内部依赖关系。
  • 如果您必须使用在此库中关闭的隔离部件来测试库,这很奇怪。你有编译器错误。我认为唯一的方法是使用反射和修改类访问修饰符。
  • @MariuszMączkowski,我同意你的 cmets。我可能不得不倾向于反射方法。或者只是重命名我的测试包以匹配被集成到被测应用程序中的 SDK。后者没试过……
  • 能否请您详细说明:此方法不是静态的。那么您打算如何将 Foo 类的 mocked 对象传递到您的测试类中 - 考虑到 Foo 不可用的事实?换句话说:请向我们展示您的测试方法在做什么。

标签: java android unit-testing mockito powermock


【解决方案1】:

你所描述的暗示你单元测试是错误的。

为了将一个单元与其依赖项隔离,你模拟你所依赖的对象

来自那里:鉴于 Foo 是包保护的事实 - 您的代码应该不可能直接引用 Foo。因此,您考虑操纵 Foo 的事实更多地表明您组合了一个有问题的设计。

从这个意义上说:我建议您仔细研究您的需要以控制 Foo。因为在 sane 设计中,您不必担心超出您的范围的包保护类。花时间改进你的设计;而不是浪费时间解决损坏设计的效果

【讨论】:

  • 感谢您的回复。我完全同意。在一个理智的世界里,你说的绝对是真的。当你是一名测试工程师并且你不能改变你正在测试的代码时怎么办?说服工程师他们需要更改代码以便您可以测试它是另一个挑战。我们不是单元测试。我们正在进行系统和 API 测试,需要能够控制一些只能被蜂窝网络检测到的应用程序内部。即检测拥塞程度。此级别的 Android 测试不适合胆小的人。我们必须发挥创造力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-11
  • 1970-01-01
  • 2015-08-23
  • 2011-06-12
  • 1970-01-01
  • 2016-01-24
  • 2019-03-07
相关资源
最近更新 更多