2

当我启动应用程序时,MySQL 中的离线数据库运行良好,但我想让它也适用于我的单元测试!

但它告诉我“ rdbms ”包丢失了。

可能是我错过了导入或其他什么,因为我得到了以下异常:

java.lang.AssertionError: Exception = com.google.apphosting.api.ApiProxy$CallNotFoundException: The API package 'rdbms' or call 'OpenConnection()' was not found.
    at org.junit.Assert.fail(Assert.java:93)
    at testDb.DbUserUnitTestCase.testAdd(DbUserUnitTestCase.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:30)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:24)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

看起来我不是唯一一个有麻烦的人:

4

2 回答 2

3

好的,我遇到了同样的问题,终于可以让它工作了。以下是问题的摘要:

  1. com.google.appengine.api.rdbms.AppEngineDriver 驱动程序仅在您在实际 App Engine 或本地 App Engine 开发环境中运行时才有效。当您仅在单元​​测试中或在 App Engine 之外运行时,它不起作用(给出此“rdbms”包丢失错误)。即使您将 rdbms.driver 系统属性设置为其他值也是如此。
  2. 在非 App Engine java 进程中工作的驱动程序是 com.google.cloud.sql.Driver。
  3. 不幸的是,如果您使用 DriverManager.getConnection() 加载驱动程序(大多数数据源都会这样做),事情就会变得棘手。此方法查看已注册的驱动程序以查看哪个驱动程序可以加载提供的 URL。因此,如果您同时注册 AppEngineDriver 和 com.google.cloud.sql.Driver,您将会遇到麻烦 - 当您加载 jdbc:google:rdbms DB URL 时,可能会使用“错误的”。

就我而言,我使用的是 maven、Spring 和 iBatis。我的解决方案是,在运行测试用例时,我使用 Spring 的 SimpleDriverDataSource。此数据源让您可以使用 ACTUAL 驱动程序实例,而不仅仅是指定类名。这意味着您不必担心在您的类路径中同时拥有 AppEngineDriver 和 com.google.cloud.sql.Driver:

<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
    <constructor-arg>
        <bean class="com.google.cloud.sql.Driver"/>
    </constructor-arg>
    <constructor-arg value="jdbc:google:rdbms://myProject:myInstance/myDb"/>
</bean>

另外,请注意 com.google.cloud.sql.Driver 似乎没有打包在任何标准的 Maven 工件中。相反,它位于 appengine-java-sdk-1.7.3/lib/impl/google_sql.jar 的 appengine-java-sdk 中。对我来说,google_sql.jar 中还有其他东西与我拥有的其他依赖项(一些杰克逊库)发生冲突,所以我只将 com.google 包提取到一个单独的 jar 中。然后我将这个 jar 添加到我在 maven 中的依赖项中,如下所述:https ://devcenter.heroku.com/articles/local-maven-dependencies 。然后,我将此作为依赖项添加到具有测试范围的项目中。

于 2012-12-07T03:31:53.603 回答
1

我想我会回答我自己的问题,我找到了解决这个问题的方法

    if(isUnitTesting) {

        String url = "jdbc:mysql://localhost:3306/project";

        connection = DriverManager.getConnection(url, "root","");

    } else {

        DriverManager.registerDriver(new AppEngineDriver());
        connection = DriverManager.getConnection("jdbc:google:rdbms://"+instanceName+"/project");

    }

我想这不是最好的方式,所以如果您有更好的答案,请随时回复!

于 2012-10-04T15:28:06.467 回答