2013-07-14 35 views
1

我正在使用MongoDB,Java,JDO和Maven。如何編寫數據庫單元測試?

我跑了存儲一些垃圾數據,並從MongoDB中取出它,它看起來確定一個簡單的主應用程序,但我要開始寫適當的單元測試。嘲笑實際的數據庫交互對我來說似乎沒有什麼幫助,所以在技術上我想編寫功能測試來檢查與數據庫的完整交互。

我的單元測試的設置是這樣的:

static final Logger LOG = LoggerFactory.getLogger(DaoTest.class); 
static final int PORT = 100001; 
static Process mongod; 
static PersistenceManagerFactory pmf; 

// Class under test. 
Dao dao; 

@BeforeClass 
public static void beforeAll() throws Exception { 
    File mongoDir = new File(
     System.getProperty("java.io.tmpdir"), 
     "mongodb-" + System.currentTimeMillis()); 
    mongoDir.deleteOnExit(); 
    mongod = Runtime.getRuntime().exec(String.format(
     "/bin/sh -c mongod --dbpath=%s --port=%d", 
     mongoDir.getAbsolutePath(), 
     PORT)); 
    LOG.info("Mongodb using {} on port {}.", mongoDir.getAbsolutePath(), PORT); 
    Thread.sleep(1000); 
    pmf = JDOHelper.getPersistenceManagerFactory("mongodbtest"); 
    LOG.info("DB connection URL: {}.", pmf.getConnectionURL()); 
} 

@AfterClass 
public static void afterAll() throws Exception { 
    mongod.destroy(); 
} 

@Before 
public void setUp() throws Exception { 
    dao = new Dao(pmf); 
} 

的src /測試/資源/ META-INF/persistence.xml中是這樣的:

<?xml version="1.0" encoding="UTF-8" ?> 
<persistence ...> 
    <persistence-unit name="mongodbtest"> 
    <properties> 
     <property name="javax.jdo.PersistenceManagerFactoryClass" 
      value="org.datanucleus.api.jdo.JDOPersistenceManagerFactory" /> 
     <property name="javax.jdo.option.ConnectionURL" value="mongodb://localhost:100001/contacts"/> 
     <property name="javax.jdo.option.RetainValues" value="true"/> 
     <property name="datanucleus.autoCreateSchema" value="true" /> 
     <property name="datanucleus.validateTables" value="false" /> 
     <property name="datanucleus.validateConstraints" value="false" /> 
     <property name="datanucleus.storeManagerType" value="mongodb" /> 
    </properties> 
    </persistence-unit> 
</persistence> 

最後,我執行我的單位使用mvn clean test進行測試,並且只有在添加嘗試保存數據的實際測試時才能運行。我收到以下錯誤:

Mongodb using /var/folders/00/0l550000h01000cxqpysvccm002cmm/T/mongodb-1373820849219 on port 100001. 
DB connection URL: mongodb://localhost:100001/contacts. 
Jul 14, 2013 12:54:10 PM com.mongodb.DBTCPConnector initDirectConnection 
WARNING: Exception executing isMaster command on localhost/127.0.0.1:27017 
java.io.IOException: couldn't connect to [localhost/127.0.0.1:27017] bc:java.net.ConnectException: Connection refused 
    at com.mongodb.DBPort._open(DBPort.java:214) 
    at com.mongodb.DBPort.go(DBPort.java:107) 

... 

Jul 14, 2013 12:54:10 PM com.mongodb.DBTCPConnector initDirectConnection 
WARNING: Exception executing isMaster command on localhost/127.0.0.1:27017 
java.io.IOException: couldn't connect to [localhost/127.0.0.1:27017] bc:java.net.ConnectException: Connection refused 
    at com.mongodb.DBPort._open(DBPort.java:214) 
    at com.mongodb.DBPort.go(DBPort.java:107) 

... 

ul 14, 2013 12:54:10 PM com.mongodb.DBPortPool gotError 
WARNING: emptying DBPortPool to localhost/127.0.0.1:27017 b/c of error 
java.io.IOException: couldn't connect to [localhost/127.0.0.1:27017] bc:java.net.ConnectException: Connection refused 
    at com.mongodb.DBPort._open(DBPort.java:214) 
    at com.mongodb.DBPort.go(DBPort.java:107) 

... 

Jul 14, 2013 12:54:10 PM org.datanucleus.store.valuegenerator.AbstractGenerator obtainGenerationBlock 
INFO: Error encountered allocating block of IDs : can't call something : localhost/127.0.0.1:27017//localhost:100001/contacts 

127.0.0.1:27017是mongodb的默認設置,但我不知道它爲什麼使用它。我可以看到它從我的persistence.xml文件中獲取配置,所以我很困惑。蒙戈docs說連接字符串URL格式爲:

mongodb://[username:[email protected]]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]] 

到目前爲止,我只基於Maven運行這個,因爲這是唯一的,只要我有這麼遠,但另外一個問題我必須最終是如何在Eclipse中運行這些單元測試。我假設這些測試需要在Eclipse中運行,並且我不知道如何設置。

我猜我並不想這樣做,雖然第一人。在Java中編寫功能數據庫測試是否有任何標準做法?我是否全都錯了?

+0

你看看nosql-unit/jongo了嗎?我認爲是一個更好的解決方案,然後從Java代碼運行mongod。 –

回答

0

要回答我的問題。有三個問題:

1)的連接字符串應該是:

mongo:/127.0.0.1/contacts 

(注意少了一個 「/」)

2)我需要添加mongoDir.mkdir();

3)啓動服務器應該是

String command = String.format(
    "/bin/sh -c mongod --dbpath=%s --port=%d", 
    mongoDir.getAbsolutePath(), 
    PORT); 
Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", command }); 

其實我結束了這個創建JUnit4亞軍,所以我可以在整個所有的測試相同的數據庫,並留給各個測試管理命令該數據庫的狀態。

0

如果你想運行一個數據庫實例來測試(只運行Maven構建運行的時間),那麼你可能會對我基於flapdoodle嵌入式Mongo API編寫的Maven插件感興趣:

embedmongo-maven-plugin

一個好處是,插件自動下載蒙戈分佈,所以沒有必要爲人們安裝蒙戈纔可以運行Maven構建。移動到不同的Mongo版本也很容易;你只需改變插件配置。