如何使用 @Configuration class 覆盖 xml 中定义的 spring bean 定义以进行 jerseytest
How to override spring bean definition defined in xml with @Configuration class for jerseytest
一段时间以来,我一直在努力解决这个问题,但无法让它发挥作用。我正在使用 spring 版本 3.2.3.RELEASE,我认为这可能会导致我遇到一些问题。我的目标是用一个导入了 configuration.The 的配置文件覆盖 xml 中定义的 bean带有模拟实现的实现。但是,这对我不起作用。如有任何建议,我们将不胜感激。
这是我的 bean 定义 class,我在其中定义了几个 bean。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="rest-common.xml"/>
<context:property-placeholder location="classpath:module.properties"/>
<bean name="vcheckResource" class="com.foo.vcheck.resources.VcheckResource" />
<bean name="vcheckProvider" class="com.foo.vcheck.provider.VcheckProvider" />
<bean name="Vcheck" class="com.foo.vcheck.provider.VcheckMessageRouter" />
</beans>
这里是生产@Configuration class 我在其中导入 bean 配置文件。
@Configuration
@Import(RestAppConfig.class)
@ImportResource({VcheckAppConfig.ModuleResources})
public class VcheckAppConfig {
public static final String ModuleResources = "classpath:bcpbx-api-vcheck-rest-beans.xml";
}
这是我的测试配置 class,我想在其中使用我的 Mockito 模拟覆盖实现,并且在单元测试中应该使用这些模拟 class 注入生产代码。但是,无论出于何种原因,xml 配置中的 bean 都不会被覆盖。如果我删除导入,它将使用来自此 class 的 bean,所以我知道这是有效的。这可能与 spring 的 3.x 版本有关吗?
@Configuration
@Import(VcheckAppConfig.class)
public class TestAppConfig {
@Bean
public Account testAccount() {
return new Account("TEST_ACCOUNT", new Vendor("TEST_VENDOR"));
}
@Bean(name ="vcheckResource")
public VcheckResource vcheckResource() {
return new VcheckResource(vcheckProvider(), new UUIDGenerator());
}
@Bean(name="vcheckProvider")
public IVcheckProvider vcheckProvider() {
System.out.println("CALLIGN GET MOCK");
return Mockito.mock(VcheckProvider.class);
}
@Bean
public IMessageRouter messageRouter() {
return Mockito.mock(IMessageRouter.class);
}
@Bean
public ICommandResponseCallbackRegistry responseRegistry() {
return Mockito.mock(ICommandResponseCallbackRegistry.class);
}
}
spring似乎无法做到这一点。
How do I override a Spring bean definition yet still reference the overridden bean?
我转换为使用 spring-mockito 并使用另一个 bean xml 文件来添加模拟。然后导入两个配置 xml 文件。这在我的单元测试中与 spring mockito 一起工作得很好。我确实必须更改我的 mockito 版本以使用 1.9.0 以与 spring mockito 兼容。
https://bitbucket.org/kubek2k/springockito/wiki/Home
@Configuration
@ImportResource({VcheckAppConfig.ModuleResources, TestAppConfig.MockModuleResources})
public class TestAppConfig {
public static final String MockModuleResources = "classpath:bcpbx-api-vcheck-rest-beans-mock.xml";
@Bean
public Account testAccount() {
return new Account("TEST_ACCOUNT", new Vendor("TEST_VENDOR"));
}
}
这是我的模拟示例,我在其中使用简单模拟重写了我的提供者的实现。我能够
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mockito="http://www.mockito.org/spring/mockito"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.mockito.org/spring/mockito http://www.mockito.org/spring/mockito.xsd">
<mockito:mock id="vcheckProvider" class="com.foo.vcheck.provider.VcheckProvider" />
</beans>
作为旁注,我将 post 这也是因为它是一个很好的解决方案,允许我使用 spring 依赖项注入进行球衣测试。
public abstract class AbstractSpring3JerseyTest implements ApplicationContextAware {
private static final Logger logger = Logger.getLogger(AbstractSpring3JerseyTest.class.getName());
private JerseyTest jerseyTest;
private ApplicationContext applicationContext;
@Before
public void setup() throws Exception {
jerseyTest.setUp();
}
@After
public void tearDown() throws Exception {
jerseyTest.tearDown();
}
protected Application configure(ApplicationContext appContext) {
ResourceConfig resourceConfig = ResourceConfig.forApplication(new RestApplication());
resourceConfig.property("contextConfig", appContext);
resourceConfig.register(SpringLifecycleListener.class).register(RequestContextFilter.class);
resourceConfig.packages(getResourcePackages());
resourceConfig.register(new RestAuthenticationFilter());
resourceConfig.property(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, "true");
resourceConfig.register(new LoggingFilter(logger, 20000));
return resourceConfig;
}
protected abstract String[] getResourcePackages();
public static void setDebugLevel(Level level) {
Logger anonymousLogger = LogManager.getLogManager().getLogger("");
Handler[] handlers = anonymousLogger.getHandlers();
anonymousLogger.setLevel(level);
for (Handler h : handlers) {
if (h instanceof ConsoleHandler)
h.setLevel(level);
}
}
public final WebTarget target() {
return jerseyTest.target();
}
public final WebTarget target(final String path) {
return jerseyTest.target().path(path);
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* Set the ApplicationContext that this object runs in. Normally this call
* will be used to initialize the object.
* <p>
* Invoked after population of normal bean properties but before an init
* callback such as
* {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
* or a custom init-method. Invoked after
* {@link ResourceLoaderAware#setResourceLoader},
* {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
* {@link MessageSourceAware}, if applicable.
*
* @param applicationContext
* the ApplicationContext object to be used by this object
* @throws ApplicationContextException
* in case of context initialization errors
* @throws BeansException
* if thrown by application context methods
* @see org.springframework.beans.factory.BeanInitializationException
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
jerseyTest = new JerseyTest(configure(applicationContext)) {
};
}
}
这是一个简单的测试,用于验证所有部件是否正常工作。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestAppConfig.class } )
public class TestVcheckResourceJersey extends AbstractSpring3JerseyTest {
@Inject
IVcheckProvider vcheckProvider;
@Test
public void testCheckNpanxx() throws ProviderException {
Assert.assertNotNull(vcheckProvider);
}
}
一段时间以来,我一直在努力解决这个问题,但无法让它发挥作用。我正在使用 spring 版本 3.2.3.RELEASE,我认为这可能会导致我遇到一些问题。我的目标是用一个导入了 configuration.The 的配置文件覆盖 xml 中定义的 bean带有模拟实现的实现。但是,这对我不起作用。如有任何建议,我们将不胜感激。
这是我的 bean 定义 class,我在其中定义了几个 bean。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<import resource="rest-common.xml"/>
<context:property-placeholder location="classpath:module.properties"/>
<bean name="vcheckResource" class="com.foo.vcheck.resources.VcheckResource" />
<bean name="vcheckProvider" class="com.foo.vcheck.provider.VcheckProvider" />
<bean name="Vcheck" class="com.foo.vcheck.provider.VcheckMessageRouter" />
</beans>
这里是生产@Configuration class 我在其中导入 bean 配置文件。
@Configuration
@Import(RestAppConfig.class)
@ImportResource({VcheckAppConfig.ModuleResources})
public class VcheckAppConfig {
public static final String ModuleResources = "classpath:bcpbx-api-vcheck-rest-beans.xml";
}
这是我的测试配置 class,我想在其中使用我的 Mockito 模拟覆盖实现,并且在单元测试中应该使用这些模拟 class 注入生产代码。但是,无论出于何种原因,xml 配置中的 bean 都不会被覆盖。如果我删除导入,它将使用来自此 class 的 bean,所以我知道这是有效的。这可能与 spring 的 3.x 版本有关吗?
@Configuration
@Import(VcheckAppConfig.class)
public class TestAppConfig {
@Bean
public Account testAccount() {
return new Account("TEST_ACCOUNT", new Vendor("TEST_VENDOR"));
}
@Bean(name ="vcheckResource")
public VcheckResource vcheckResource() {
return new VcheckResource(vcheckProvider(), new UUIDGenerator());
}
@Bean(name="vcheckProvider")
public IVcheckProvider vcheckProvider() {
System.out.println("CALLIGN GET MOCK");
return Mockito.mock(VcheckProvider.class);
}
@Bean
public IMessageRouter messageRouter() {
return Mockito.mock(IMessageRouter.class);
}
@Bean
public ICommandResponseCallbackRegistry responseRegistry() {
return Mockito.mock(ICommandResponseCallbackRegistry.class);
}
}
spring似乎无法做到这一点。
How do I override a Spring bean definition yet still reference the overridden bean?
我转换为使用 spring-mockito 并使用另一个 bean xml 文件来添加模拟。然后导入两个配置 xml 文件。这在我的单元测试中与 spring mockito 一起工作得很好。我确实必须更改我的 mockito 版本以使用 1.9.0 以与 spring mockito 兼容。
https://bitbucket.org/kubek2k/springockito/wiki/Home
@Configuration
@ImportResource({VcheckAppConfig.ModuleResources, TestAppConfig.MockModuleResources})
public class TestAppConfig {
public static final String MockModuleResources = "classpath:bcpbx-api-vcheck-rest-beans-mock.xml";
@Bean
public Account testAccount() {
return new Account("TEST_ACCOUNT", new Vendor("TEST_VENDOR"));
}
}
这是我的模拟示例,我在其中使用简单模拟重写了我的提供者的实现。我能够
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mockito="http://www.mockito.org/spring/mockito"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.mockito.org/spring/mockito http://www.mockito.org/spring/mockito.xsd">
<mockito:mock id="vcheckProvider" class="com.foo.vcheck.provider.VcheckProvider" />
</beans>
作为旁注,我将 post 这也是因为它是一个很好的解决方案,允许我使用 spring 依赖项注入进行球衣测试。
public abstract class AbstractSpring3JerseyTest implements ApplicationContextAware {
private static final Logger logger = Logger.getLogger(AbstractSpring3JerseyTest.class.getName());
private JerseyTest jerseyTest;
private ApplicationContext applicationContext;
@Before
public void setup() throws Exception {
jerseyTest.setUp();
}
@After
public void tearDown() throws Exception {
jerseyTest.tearDown();
}
protected Application configure(ApplicationContext appContext) {
ResourceConfig resourceConfig = ResourceConfig.forApplication(new RestApplication());
resourceConfig.property("contextConfig", appContext);
resourceConfig.register(SpringLifecycleListener.class).register(RequestContextFilter.class);
resourceConfig.packages(getResourcePackages());
resourceConfig.register(new RestAuthenticationFilter());
resourceConfig.property(ServerProperties.RESPONSE_SET_STATUS_OVER_SEND_ERROR, "true");
resourceConfig.register(new LoggingFilter(logger, 20000));
return resourceConfig;
}
protected abstract String[] getResourcePackages();
public static void setDebugLevel(Level level) {
Logger anonymousLogger = LogManager.getLogManager().getLogger("");
Handler[] handlers = anonymousLogger.getHandlers();
anonymousLogger.setLevel(level);
for (Handler h : handlers) {
if (h instanceof ConsoleHandler)
h.setLevel(level);
}
}
public final WebTarget target() {
return jerseyTest.target();
}
public final WebTarget target(final String path) {
return jerseyTest.target().path(path);
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* Set the ApplicationContext that this object runs in. Normally this call
* will be used to initialize the object.
* <p>
* Invoked after population of normal bean properties but before an init
* callback such as
* {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
* or a custom init-method. Invoked after
* {@link ResourceLoaderAware#setResourceLoader},
* {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
* {@link MessageSourceAware}, if applicable.
*
* @param applicationContext
* the ApplicationContext object to be used by this object
* @throws ApplicationContextException
* in case of context initialization errors
* @throws BeansException
* if thrown by application context methods
* @see org.springframework.beans.factory.BeanInitializationException
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
jerseyTest = new JerseyTest(configure(applicationContext)) {
};
}
}
这是一个简单的测试,用于验证所有部件是否正常工作。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestAppConfig.class } )
public class TestVcheckResourceJersey extends AbstractSpring3JerseyTest {
@Inject
IVcheckProvider vcheckProvider;
@Test
public void testCheckNpanxx() throws ProviderException {
Assert.assertNotNull(vcheckProvider);
}
}