ClassCastException: org.springframework.beans.factory.support.NullBean 无法转换为 org.springframework.plugin.core.Plugin

ClassCastException: org.springframework.beans.factory.support.NullBean cannot be cast to org.springframework.plugin.core.Plugin

我的应用程序中有这个测试:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = ApplicationTestConfig.class)
@MockBeans({ @MockBean(SwaggerConfig.class)})
public class AuthorisationControllerTest implements WebMvcConfigurer {

    private MockMvc mockMvc;

    @Autowired
    private WebApplicationContext wac;


    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    }

    @Test
    public void testAuthorisation() throws Exception {
        this.mockMvc.perform(get("/test")).andDo(print()).andExpect(status().isOk())
                .andExpect(content().string(containsString("Hello, World")));
    }


}

但是当我 运行 测试时我得到了这个错误:

15:04:10.417 [main] ERROR org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@7219ec67] to prepare test instance [eu.europa.ec.oib.kw.guards.controller.AuthorisationControllerTest@6fb219dd]
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:132)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:123)
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access0(ParentRunner.java:66)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:293)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273)
    at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
    at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159)
    at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384)
    at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:345)
    at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418)
Caused by: org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.ClassCastException: org.springframework.beans.factory.support.NullBean cannot be cast to org.springframework.plugin.core.Plugin
    at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:185)
    at org.springframework.context.support.DefaultLifecycleProcessor.access0(DefaultLifecycleProcessor.java:53)
    at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:360)
    at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:158)
    at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:122)
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554)
    at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:129)
    at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:61)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:275)
    at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:243)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    ... 28 common frames omitted
Caused by: java.lang.ClassCastException: org.springframework.beans.factory.support.NullBean cannot be cast to org.springframework.plugin.core.Plugin
    at org.springframework.plugin.core.PluginRegistrySupport.initialize(PluginRegistrySupport.java:78)
    at org.springframework.plugin.core.OrderAwarePluginRegistry.initialize(OrderAwarePluginRegistry.java:132)
    at org.springframework.plugin.core.PluginRegistrySupport.getPlugins(PluginRegistrySupport.java:59)
    at org.springframework.plugin.core.SimplePluginRegistry.getPlugins(SimplePluginRegistry.java:68)
    at springfox.documentation.spring.web.plugins.DocumentationPluginsManager.documentationPlugins(DocumentationPluginsManager.java:96)
    at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.start(DocumentationPluginsBootstrapper.java:162)
    at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:182)
    ... 40 common frames omitted
15:04:10.436 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - After test class: context [DefaultTestContext@769e7ee8 testClass = AuthorisationControllerTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@5276e6b0 testClass = AuthorisationControllerTest, locations = '{}', classes = '{class com.bonanza.ApplicationTestConfig}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@491666ad, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@51931956, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@82791545, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@240237d2, org.springframework.test.context.web.socket.MockServerContainerContextCustomizer@212bf671], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.test.context.web.WebDelegatingSmartContextLoader', parent = [null]], attributes = map[[empty]]], class annotated with @DirtiesContext [false] with mode [null].
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 10.803 s <<< FAILURE! - in com.bonanza..controller.AuthorisationControllerTest
[ERROR] testAuthorisation(om.bonanza.controller.AuthorisationControllerTest)  Time elapsed: 0.049 s  <<< ERROR!
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.ClassCastException: org.springframework.beans.factory.support.NullBean cannot be cast to org.springframework.plugin.core.Plugin
Caused by: java.lang.ClassCastException: org.springframework.beans.factory.support.NullBean cannot be cast to org.springframework.plugin.core.Plugin
[INFO] 

您的问题可能与以下行有关:

@MockBeans({ @MockBean(SwaggerConfig.class)})

我认为 Spring 试图模拟您的 Swagger 配置,并且在解析依赖项时,框架提供了一个 NullBean 引用而不是所需的对象,一个 org.springframework.plugin.core.Plugin 的实例在这种情况下。

我假设您需要在测试中禁用 Swagger 支持。

如果是这种情况,还有一种更简单的方法可以继续。

想法是组合 Spring 个配置文件。

首先,在您的 Swagger class 配置中定义一个 @Profile 注释,例如:

@Profile("swagger")
@Configuration
@EnableSwagger2
public class SwaggerConfig {
  //...
}

此配置文件应包含在您的正常应用程序操作中。如果您需要这方面的更多信息,请告诉我。

然后,在您的测试中,select 您想要使用 @ActiveProfiles 注释启用的配置文件,例如:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = ApplicationTestConfig.class)
@ActiveProfiles("test")
public class AuthorisationControllerTest implements WebMvcConfigurer {

您可以像示例中那样定义名称为 test 的单个配置文件,其中包含配置文件列表,或者直接包含适用的配置文件列表,但务必确保不包含与Swagger 配置,示例中的 swagger

或者,如果它不干扰您的其他配置,您可以通过以下配置获得类似的结果:

@Profile("!no-swagger")
@Configuration
@EnableSwagger2
public class SwaggerConfig {
  //...
}

你的测试:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = ApplicationTestConfig.class)
@ActiveProfiles("no-swagger")
public class AuthorisationControllerTest implements WebMvcConfigurer {