简体   繁体   中英

Spring MVC testing, JNDI

I would like to bind an existing data source to a JNDI name for my tests.

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = { "file:WebContent/WEB-INF/application-context.xml",
        "file:WebContent/WEB-INF/test-datasource.xml" })
public class SimulatorTest {

    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

    @PostConstruct
    public void createContext() throws NamingException {
        SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
        builder.bind("java:comp/env/jdbc/DefaultDB", dataSource);
        builder.activate();
    }
...

This seems to work but as soon as my code (ie EclipseLink) tries to look up this JNDI name, it fails:

Exception Description: Cannot acquire data source [java:comp/env/jdbc/DefaultDB].
Internal Exception: javax.naming.OperationNotSupportedException: SimpleNamingContext does not support [javax.naming.Name]

I've looked at the source code and it really doesn't: https://github.com/spring-projects/spring-framework/blob/master/spring-test/src/main/java/org/springframework/mock/jndi/SimpleNamingContext.java#L225-L293

How can I create a context so EclipseLink does not fail to look up the data source?

Solved my issue. Just avoid using JNDI during tests, at least that's also what many people suggest.

In my code, I was creating an EntityManagerFactory manually that looks up the JNDI string defined in the persistence.xml. This was failing during test time due to missing JNDI.

Now, I let Spring create the EntityManagerFactory for me and let Spring pick the DataSource.

<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="persistenceUnitName" value="MyPU" />
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
    <property name="jpaDialect">
        <bean class="org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect" />
    </property>
    <property name="jpaPropertyMap">
        <props>
            <prop key="eclipselink.logging.level">INFO</prop>
            <prop key="eclipselink.weaving">false</prop>
        </props>
    </property>
</bean>

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/DefaultDB" expected-type="javax.sql.DataSource" />

The advantage of not defining the JNDI name of the data source in the persistence.xml but in the spring configuration, is that Spring can overwrite the dataSource bean during testing - so now JNDI lookup, no failing tests.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM