首页 > 解决方案 > 在 Spring 上下文初始化期间使用 PowerMock

问题描述

我正在尝试为我没有编写并且不想更改任何代码的实现的项目编写集成测试套件。现在在该代码中有一个名为 SalesforceSubscriptionsManager 的类,它是一个 Spring Bean(组件),它调用 SalesforceBusSubscriber 的构造函数。

@Component
public class SalesforceSubscriptionsManager {
    public SalesforceSubscriptionsManager() {
        System.out.println("creating bean");
        //implementation remove for brevity
        new SalesforceBusSubscriber(credentials, consumer);
    }
}

我试图模拟 SalesforceBusSubscriber 类的实例化,因此在设置应用程序上下文并创建 bean 时,它不使用真正的订阅者类。为此,我正在使用 PowerMock。这是我的测试的样子:

@SpringBootTest
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringRunner.class)
@ContextConfiguration(
        classes = {Application.class},
        initializers = { ConfigFileApplicationContextInitializer.class, SalesforceBusSubscriber.class }
)
@PrepareForTest({SalesforceBusSubscriber.class})
@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "javax.xml.transform.*", "org.xml.*", "javax.management.*", "javax.net.ssl.*", "com.sun.org.apache.xalan.internal.xsltc.trax.*"})
public class BaseTest {
    @ClassRule
    public static PreContextMockRule mock = new PreContextMockRule();

    @Test
    public void test() throws Exception {
        SalesforceBusSubscriber postContext = new SalesforceBusSubscriber(
            new SalesforceBusCredentials(1L,"http://www.google.com", "user","pass","d"),
            Mockito.mock(Consumer.class)
        );
    }
}

我创建的规则如下所示:

/**
 * Rule to allow powermock behaviour before spring context is initiated so that when the context
 * runs they are already applied.
 */
public class PreContextMockRule extends ExternalResource {
    protected void before() throws Throwable {
        System.out.println("running rule");

        SalesforceBusSubscriber mockSubscriber = mock(SalesforceBusSubscriber.class);

        whenNew(SalesforceBusSubscriber.class)
                .withArguments(any(SalesforceBusCredentials.class), any(AbstractConsumer.class))
                .thenReturn(mockSubscriber);

        when(mockSubscriber.getErrorFlag()).thenReturn(false);
    }

    protected void after() {
        System.out.println("after");
    }
}

现在,当我构建代码并运行时,我看到以下内容:

running rule
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot :: 

//more stuff

creating bean

所以powermock在上下文启动之前运行,上下文被启动,然后bean被创建。然而,当单步执行代码时,构造函数中的 SaleforceBusSubscriber 不是一个模拟,但名为“test”的方法中名为“postContext”的那个是一个模拟......

我的问题是,如何让 powermock 模拟 spring bean 中新对象的实例化?

PS我知道另一种方法是隔离工厂中对象的创建并模拟该工厂,但我不想更改任何现有代码。

标签: javaspringspring-bootintegration-testingpowermock

解决方案


推荐阅读