Powermockito期望在线程中创建对象时不工作



我在一些单元测试中使用了powermockit,并且遇到了一个问题。我正在尝试测试一种方法,该方法创建了一系列线程并运行它们。在每个线程中,创建一个我需要期望的对象,而不是返回我自己的模拟对象(它发出http请求等)。在使用PowerMockito.whenNew(...)之前,我已经这样做了,它工作得很好,但这似乎不工作- PowerMockito在线程内不工作吗?我没能找到任何其他类似的问题或关于这种情况的文档。

帮助您可视化的一些示例代码:

for(Object object : objectList) {
    Thread t = new Thread(new Runnable() {
        public void run() {
            SomeObject objectImTryingToStub = new SomeObject();
        }
    });
}

我用来尝试捕获对象创建的代码:

SomeObject mockSomeObject = mock(SomeObject.class);
PowerMockito.whenNew(SomeObject.class).withNoArguments().thenReturn(mockSomeObject);

相同的代码在同一类中的其他测试中运行良好,这些测试成功地捕获了以相同方式创建的相同类型的对象。

任何帮助都是感激的!由于

来晚了,但我认为正确的解决方案仍然缺失。如您所知,您必须PrepareForTest类,做对象创建您试图模拟。不那么明显的是这里实际进行创建的类。这个类就是内部匿名的Runnable类。该类的名称是在编译时生成的,在单元测试中不容易确定。假设提取代码片段的类是com.example.SomeClass,那么您需要的语句可能类似于:

@PrepareForTest(com.example.SomeClass$4.class)
但更简单的方法是使用另一种允许通配符的注释形式:
@PrepareForTest("com.example.*")

只是尽量保持通配符匹配器尽可能紧密,这样PowerMock就不必准备所有类来运行测试。

我在我的项目中遇到了同样的问题,在做了一些挖掘之后,实际上不是线程导致问题本身,而是对象是在派生自Runnable的匿名类中创建的。

在PowerMock的文档中,查看第二个要点,您需要放置正在进行创建的类,而不是在PrepareForTest中实例化的类。

所以您需要使用PrepareForTest注释您的测试,以准备在运行时创建的匿名类。通常,它应该是Runnable$n其中n是在运行时为您计算的某个数字。那么你如何得到一个静态未知的类呢?幸运的是,PrepareForTest在其fullqualifiednames中也接受字符串,因此您需要将PrepareForTest更改为如下内容:

@PrepareForTest( fullyQualifiedNames = {"com.whatever_package_that_SomeObject_is_in.*"}, value = {SomeStaticlyKnowClass.class} )

最近我遇到了同样的问题,并找到了一个解决方案。真正发生的事情是Runnable的内部声明将踢出所有mock !因为Runnable类是由bootstrap Classloader加载的,所以PowerMock无法模拟其中的任何动作。解决方案(对我来说)是在Runnable内部类之外声明实例化。

对于任何遇到类似问题的人,我已经深入研究了一下,似乎这个功能不能完全用于线程。我试着让它在创建时抛出一个FNF异常——在线程内部它什么也不做,而如果我把对象创建放在线程段之前,它就会像预期的那样工作。我不知道为什么会这样,但至少我现在有了一个明确的答案。如果有人知道解决这个问题的方法,请告诉我。

由于您没有显示太多代码,我不得不猜测您错过了正在进行"new"调用的类的"@PrepareForTest"条目,很可能是您的CUT(在测试中的类)。

相关内容

  • 没有找到相关文章

最新更新