2013-02-11 61 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", "");