Mule junit测试和内存中嵌入式数据库:无法处理上下文

时间:2014-01-22 21:19:22

标签: jdbc mule derby h2

我正在为遗留项目添加测试。该项目使用Apache Commons的BasicDataSource定义JDBC数据源。我已对其进行了更新,以便从mvn verify运行时,URL(来自测试属性文件)指定H2连接字符串。我的测试通过,但在拆除时,在处理MuleContext时会抛出异常,导致我的所有测试都报告为失败。

我目前的解决方法是在muleContext = null方法中设置@After,以避免清除调度程序池,这是抛出异常的地方。这是极端的hacky,但似乎确实有效。所以我想知道如何更好地解决这个问题。

例外是:

ERROR 2014-01-23 09:51:32,632 [Thread-1] org.mule.DefaultMuleContext: Failed to stop Mule context
org.mule.api.lifecycle.LifecycleException: null
    at org.mule.lifecycle.AbstractLifecycleManager.invokePhase(AbstractLifecycleManager.java:156)
    at org.mule.transport.ConnectorLifecycleManager.fireStopPhase(ConnectorLifecycleManager.java:78)
    at org.mule.transport.AbstractConnector.stop(AbstractConnector.java:518)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.mule.lifecycle.phases.DefaultLifecyclePhase.applyLifecycle(DefaultLifecyclePhase.java:225)
    at org.mule.lifecycle.RegistryLifecycleManager$RegistryLifecycleCallback.onTransition(RegistryLifecycleManager.java:276)
    at org.mule.lifecycle.RegistryLifecycleManager.invokePhase(RegistryLifecycleManager.java:155)
    at org.mule.lifecycle.RegistryLifecycleManager.fireLifecycle(RegistryLifecycleManager.java:126)
    at org.mule.registry.AbstractRegistryBroker.fireLifecycle(AbstractRegistryBroker.java:80)
    at org.mule.registry.MuleRegistryHelper.fireLifecycle(MuleRegistryHelper.java:120)
    at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:94)
    at org.mule.lifecycle.MuleContextLifecycleManager$MuleContextLifecycleCallback.onTransition(MuleContextLifecycleManager.java:90)
    at org.mule.lifecycle.MuleContextLifecycleManager.invokePhase(MuleContextLifecycleManager.java:72)
    at org.mule.lifecycle.MuleContextLifecycleManager.fireLifecycle(MuleContextLifecycleManager.java:64)
    at org.mule.DefaultMuleContext.stop(DefaultMuleContext.java:272)
    at org.mule.DefaultMuleContext.dispose(DefaultMuleContext.java:282)
    at org.mule.tck.junit4.AbstractMuleContextTestCase.disposeContext(AbstractMuleContextTestCase.java:262)
    at org.mule.tck.junit4.AbstractMuleContextTestCase.disposeContextPerTest(AbstractMuleContextTestCase.java:251)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:37)
    at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:46)
    at org.junit.internal.runners.statements.FailOnTimeout$1.run(FailOnTimeout.java:28)
Caused by: java.lang.NullPointerException
    at org.apache.commons.pool.impl.GenericKeyedObjectPool$ObjectQueue.access$900(GenericKeyedObjectPool.java:2140)
    at org.apache.commons.pool.impl.GenericKeyedObjectPool.clear(GenericKeyedObjectPool.java:1333)
    at org.mule.transport.DefaultConfigurableKeyedObjectPool.clear(DefaultConfigurableKeyedObjectPool.java:80)
    at org.mule.transport.AbstractConnector.clearDispatchers(AbstractConnector.java:819)
    at org.mule.transport.AbstractConnector$3.onTransition(AbstractConnector.java:546)
    at org.mule.transport.AbstractConnector$3.onTransition(AbstractConnector.java:519)
    at org.mule.lifecycle.AbstractLifecycleManager.invokePhase(AbstractLifecycleManager.java:141)
    ... 30 more

我创建了一个展示问题的最小流量。将任何消息发送到vm://startTest,流程将正确地将42插入测试表。数据源配置为目前使用H2。我还用Derby验证了这一点,并在评论中包含了该配置。

<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:vm="http://www.mulesoft.org/schema/mule/vm" xmlns:jms="http://www.mulesoft.org/schema/mule/jms"
    xmlns:jdbc-ee="http://www.mulesoft.org/schema/mule/ee/jdbc"
    xmlns="http://www.mulesoft.org/schema/mule/core"
    xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:spring="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    version="EE-3.3.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd 
http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd 
http://www.mulesoft.org/schema/mule/ee/jdbc http://www.mulesoft.org/schema/mule/ee/jdbc/current/mule-jdbc-ee.xsd 
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd 
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd "
>
    <spring:bean class="org.apache.commons.dbcp.BasicDataSource" id="dataSource">
        <spring:property name="driverClassName" value="org.h2.Driver" />
        <spring:property name="url" value="jdbc:h2:mem:test;MODE=Oracle" />
        <spring:property name="validationQuery" value="SELECT 1 FROM DUAL" />
        <!--
        <spring:property name="driverClassName" value="org.apache.derby.jdbc.EmbeddedDriver" />
        <spring:property name="url" value="jdbc:derby:memory:test;create=true" />
        <spring:property name="validationQuery" value="values 1" />
        -->
        <spring:property name="testOnBorrow" value="true" />
    </spring:bean>
    <spring:bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <spring:constructor-arg ref="h2DataSource" />
    </spring:bean>
    <jdbc-ee:connector name="jdbcConnector"
        dataSource-ref="dataSource" validateConnections="true"
        queryTimeout="-1" pollingFrequency="0">
    </jdbc-ee:connector>
    <flow name="query-insert">
        <vm:inbound-endpoint path="startTest"/>
        <jdbc-ee:outbound-endpoint
            exchange-pattern="request-response" queryKey="putvalues"
            queryTimeout="-1" connector-ref="jdbcConnector">
            <jdbc-ee:query key="putvalues"
                value="insert into TEST_TABLE (A_NUMBER) values (42)" />
        </jdbc-ee:outbound-endpoint>
    </flow>
</mule>

如果您想要运行此流程,可以在测试之前调用必要的DDL:jdbcTemplate.update("create table TEST_TABLE ( A_NUMBER int )");

我正在使用Mule ESB 3.3.1,H2 1.3.174和Derby 10.6.1.0(由Mule提供)进行测试。

我想我遇到了the Mule JDBC transport reference的Derby部分中的提示警告的问题,但是该页面上建议的解决方案(使用jdbc:derby-data-source)是不可接受的,因为那将要求我修改一个工作的Mule配置文件。我很乐意重新实现jdbc:derby-data-source提供的任何解决方案,但我不知道解决方案是什么!

1 个答案:

答案 0 :(得分:1)

将Mule配置文件拆分为两个(数据库连接器和流),以便为第三个文件中的测试定义不同的数据源,并将其与包含流的文件一起加载。