我们希望在单元测试中将ejb作为Spring组件进行测试。
使用Resources注释查找如下JNDI值的ejb之一:
@Resource(lookup = "java:global/myapp/portal/url")
private String portalUrl;
问题是,Spring似乎试图按类型查找值,即它在应用程序上下文中查找java.lang.String类型的bean,而不是使用JNDI。
这是我们的代码
背景1:
<bean id="serverMock" class="myapp.JndiServerMock">
</bean>
背景2:
<context:annotation-config />
<context:component-scan base-package="myapp">
<context:include-filter type="annotation" expression="javax.ejb.Stateless" />
<context:include-filter type="annotation"
expression="javax.annotation.Resources" />
</context:component-scan>
<bean
class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
<property name="alwaysUseJndiLookup" value="true" />
</bean>
<bean id="clientMock" class="myapp.JndiClientMock">
<bean id="java:global/myapp/portal/url" class="java.lang.String">
<constructor-arg value="http://localhost:8080" type="java.lang.String"/>
</bean>
JndiServerMock:
JndiServerMock公共类{
public JndiServerMock() throws IllegalStateException, NamingException {
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
builder.bind("java:global/myapp/portal/url", "http://localhost:8080");
builder.activate();
}
}
JndiClientMock:
JndiClientMock公共类{
public JndiClientMock() throws NamingException {
Hashtable<String, String> prop = new Hashtable<String, String>();
prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.springframework.mock.jndi.SimpleNamingContextBuilder");
InitialContext ic = new InitialContext(prop);
System.err.println("result = " + ic.lookup("java:global/myapp/portal/url"));
}
}
ExampleBean:
@Stateless公共类ExampleBean {
@Resource(lookup = "java:global/myapp/portal/url")
private String portalUrl;
public ExampleBean() {
System.err.println("portalUrl = " + portalUrl);
}
}
公共类MainApp {
public static void main(String[] args) {
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.springframework.mock.jndi.SimpleNamingContextBuilder");
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("/spring/firstContext.xml",
"/spring/secondContext.xml");
ExampleBean exampleBean = applicationContext.getBean(ExampleBean.class);
}
}
如果省略了"java:global/myapp/portal/url" bean定义,则会抛出以下异常:
由以下原因引起:org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualified bean of type [java.lang. lang.]期望至少有1个bean符合此依赖的自动候选资格。依赖注释:{@javax.annotation。资源(shareable=true, lookup=java:global/myapp/portal/url),名称=,描述=,authenticationType=CONTAINER,类型=class java.lang. lang. html对象,mappedName =)}org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException (DefaultListableBeanFactory.java: 1301)org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency (DefaultListableBeanFactory.java: 1047)org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency (DefaultListableBeanFactory.java: 942)org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource (CommonAnnotationBeanPostProcessor.java: 457)org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource (CommonAnnotationBeanPostProcessor.java: 435)org.springframework.context.annotation.CommonAnnotationBeanPostProcessor ResourceElement.getResourceToInject美元(CommonAnnotationBeanPostProcessor.java: 559)org.springframework.beans.factory.annotation.InjectionMetadata InjectedElement.inject美元(InjectionMetadata.java: 169)org.springframework.beans.factory.annotation.InjectionMetadata.inject (InjectionMetadata.java: 88)org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues (CommonAnnotationBeanPostProcessor.java: 305)…13
我认为这里的问题是您如何尝试在Spring配置中设置JNDI条目—这里有一个如何做到这一点的示例。这提供了实现相同目标的其他方法的示例。但是,如果您希望在单元测试中这样做,我认为这里的JUnit部分可能是一种更简洁的方法,但看起来您确实有很多选择!