gpt4 book ai didi

unit-testing - 无法在单独的类中获取 Executor 的模拟实例

转载 作者:行者123 更新时间:2023-12-04 17:44:53 24 4
gpt4 key购买 nike

我正在尝试从 java.util.concurrent 包中模拟 ExecutorService 和 Executors 。

如果我尝试在我模拟对象的同一类(测试类)中获取对象,我能够获取模拟对象。但是,如果我尝试在不同的类(我要测试的类)中获取模拟对象,那么它会从 java.util.concurrent 返回实际对象。以下是代码片段。

我要测试的类(class):

public class MyClass
{
public void myMethod()
{
ExecutorService executorService = Executors.newFixedThreadPool(2, new MyThreadFactory());

for (int count = 0; count < 2; count++)
{
executorService.submit(new Thread());
}
}
}

class MyThreadFactory implements ThreadFactory
{
@Override
public Thread newThread(Runnable r)
{
return null;
}
}

我的测试类看起来像:
@RunWith(PowerMockRunner.class)
@PrepareForTest(Executors.class)
public class MyClassTest
{
@Test
public void testMyMethod()
{
prepareMocks();

//Code to get mocked object (See testMethod below)
}

private void prepareMocks()
{
ExecutorService executorService = PowerMock.createMock(ExecutorService.class);
EasyMock.expect(executorService.submit(EasyMock.anyObject(Runnable.class))).andReturn(null).anyTimes();

PowerMock.mockStatic(Executors.class);
EasyMock.expect(Executors.newFixedThreadPool(EasyMock.anyInt(), EasyMock.anyObject(ThreadFactory.class))).andReturn(executorService).anyTimes();

PowerMock.replay(executorService, Executors.class);
}
}

如果 MyClassTest.testMyMethod() 如下所示,则返回模拟对象。
    @Test
public void testMyMethod()
{
prepareMocks();

//Following code reurned mocked instance of ExecutorService
ExecutorService executorService = Executors.newFixedThreadPool(2, new MyThreadFactory());

for (int count = 0; count < 2; count++)
{
executorService.submit(new Thread());
}
}

但是,如果我将测试方法更改为调用 myClass.myMethod(),它将返回实际实例而不是 myMethod() 中的模拟实例。
@Test
public void testMyMethod()
{
prepareMocks();

/*
* Within myClass.myMethod(), Executors.newFixedThreadPool() returns actual instance of ThreadPoolExecutor
* instead of mocked object
*/
MyClass myClass = new MyClass();
myClass.myMethod();
}

我期望在 myClass.myMethod 中获得一个模拟的 Executors/ExecutorService 实例。

这是预期的行为吗?谁能解释这种行为?我错过了什么吗?

最佳答案

您需要让类(class)知道将有一个 Mock 传入。在您的 @PrepareForTest() ,尝试也包括调用静态的类。这样你就告诉它模拟静态的执行,以及告诉它这个模拟将在哪里发生。尝试更新 @PrepareForTest({Executors.class, MyClass.class}) .

当您拥有它以便您的测试类直接调用静态时,您将拥有 Executors.class@PrepareForTest()所以它会知道将模拟“注入(inject)”到执行中。当您调用其他类时,在运行时您正在调用的类不知道使用静态类的模拟版本,这就是为什么它使用它知道的原始代码,而不是其范围之外的模拟.添加调用静态对象(您测试的对象)的类,将允许您在运行静态模拟时被 Hook 。

关于unit-testing - 无法在单独的类中获取 Executor 的模拟实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20659949/

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