【问题标题】:Unable to get mocked instance of Executor in separate class无法在单独的类中获取 Executor 的模拟实例
【发布时间】:2013-12-18 13:48:45
【问题描述】:

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

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

我要测试的类:

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() 如下,则返回 mocked oject。

    @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 的模拟实例。

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

【问题讨论】:

    标签: unit-testing mocking easymock powermock executors


    【解决方案1】:

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

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

    【讨论】:

    猜你喜欢
    • 2010-09-17
    • 2019-07-30
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    相关资源
    最近更新 更多