2013-02-11 63 views
2

我试图在MySQL兼容模式下使用H2数据库在Play 2应用程序中运行单元测试。我在@Before其配置如下:播放2框架单元测试 - java.lang.RuntimeException:DataSource用户为空?

@Before 
public void startApp() throws Exception { 
    Map<String, String> settings = new HashMap<String, String>(); 
    settings.put("db.default.driver", "org.h2.Driver"); 
    settings.put("db.default.user", "sa"); 
    settings.put("db.default.password", ""); 
    settings.put("db.default.url", "jdbc:h2:mem:play-test-351881363;MODE=MySQL"); // TODO: use config for url 
    settings.put("db.default.jndiName", "DefaultDS"); 
    app = Helpers.fakeApplication(settings); 
    Helpers.start(app); 

    databaseTester = new JndiDatabaseTester("DefaultDS"); 

    IDataSet expectedDataSet = new FlatXmlDataSetBuilder().build(play.Play.application() 
      .resourceAsStream("/resources/dataset.xml")); 
    databaseTester.setDataSet(expectedDataSet); 
    databaseTester.onSetup(); 
} 

@After 
public void stopApp() throws Exception { 
    databaseTester.onTearDown(); 
    Helpers.stop(app); 
} 

但它会导致java.lang.RuntimeException: DataSource user is null?在实际的实验方法,当它试图访问数据库:

[ERROR] [02/12/2013 01:19:32.085] [application-akka.actor.default-dispatcher-4] [akka://application/user/load_data_task_runner_test/load_record] DataSource user is null? 
java.lang.RuntimeException: DataSource user is null? 
    at com.avaje.ebeaninternal.server.lib.sql.DataSourcePool.<init>(DataSourcePool.java:184) 
    at com.avaje.ebeaninternal.server.lib.sql.DataSourceManager.getDataSource(DataSourceManager.java:200) 
    at com.avaje.ebeaninternal.server.lib.sql.DataSourceGlobalManager.getDataSource(DataSourceGlobalManager.java:46) 
    at com.avaje.ebeaninternal.server.core.DefaultServerFactory.getDataSourceFromConfig(DefaultServerFactory.java:432) 
    at com.avaje.ebeaninternal.server.core.DefaultServerFactory.setDataSource(DefaultServerFactory.java:393) 
    at com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:169) 
    at com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:124) 
    at com.avaje.ebeaninternal.server.core.DefaultServerFactory.createServer(DefaultServerFactory.java:64) 
    at com.avaje.ebean.EbeanServerFactory.create(EbeanServerFactory.java:45) 
    at com.avaje.ebean.Ebean$ServerManager.getWithCreate(Ebean.java:206) 
    at com.avaje.ebean.Ebean$ServerManager.get(Ebean.java:193) 
    at com.avaje.ebean.Ebean$ServerManager.access$200(Ebean.java:128) 
    at com.avaje.ebean.Ebean.getServer(Ebean.java:257) 
    at play.db.ebean.Model$Finder.server(Model.java:240) 
    at play.db.ebean.Model$Finder.byId(Model.java:261) 
    at integration.LoadRecordService.onReceive(LoadRecordService.java:50) 
    at akka.actor.UntypedActor$$anonfun$receive$1.applyOrElse(UntypedActor.scala:159) 
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:425) 
    at akka.actor.ActorCell.invoke(ActorCell.scala:386) 
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:230) 
    at akka.dispatch.Mailbox.run(Mailbox.scala:212) 
    at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:502) 
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:262) 
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975) 
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1478) 
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104) 

这里变阵和初始化使用dbunit工作startApp(),例外的是扔在@Test方法中。

我做错了什么?

P.S.我没有使用play.test.Helpers.running,因为它需要Runnable作为参数,run()在runnable中不能抛出异常。因此,为了在单元测试中捕获异常,我必须将整个run()包装为try,手动捕获异常,单元测试失败和日志消息。它膨胀了很多代码。下面是running()代码:

public static synchronized void running(FakeApplication fakeApplication, final Runnable block) { 
    try { 
     start(fakeApplication); 
     block.run(); 
    } finally { 
     stop(fakeApplication); 
    } 
} 

我做同样的我@Before@After,也许除了一些线程的东西,可能是错误的原因。

回答

13

问题是由配置ebean.default关键引起主配置中注释掉:

ebean.default="models.*" 

而对于H2设置用户名和密码是 necessarry,它的工作原理没有它:

settings.put("db.default.user", "sa"); 
settings.put("db.default.password", "");