2015-11-02 145 views
0

在我的項目中,我使用JDBC,MySQL,Servlets,JSP。 爲了測試我的道的我做了一些單元測試,我試圖使用JUnit和Unitils。Unitils數據庫異常

我得到這個異常:

org.unitils.core.UnitilsException: Error inserting test data from DbUnit dataset for method public void com.jean.taxi.daoImpl.ClientDaoImplTest.testListModerators() 
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:190) 
    at org.unitils.dbunit.DbUnitModule$DbUnitListener.beforeTestSetUp(DbUnitModule.java:791) 
    at org.unitils.core.Unitils$UnitilsTestListener.beforeTestSetUp(Unitils.java:273) 
    at org.unitils.UnitilsJUnit4TestClassRunner$TestListenerInvokingMethodRoadie.runBeforesThenTestThenAfters(UnitilsJUnit4TestClassRunner.java:181) 
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87) 
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50) 
    at org.unitils.UnitilsJUnit4TestClassRunner.invokeTestMethod(UnitilsJUnit4TestClassRunner.java:95) 
    at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:59) 
    at org.unitils.UnitilsJUnit4TestClassRunner.access$000(UnitilsJUnit4TestClassRunner.java:42) 
    at org.unitils.UnitilsJUnit4TestClassRunner$1.run(UnitilsJUnit4TestClassRunner.java:60) 
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34) 
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) 
    at org.unitils.UnitilsJUnit4TestClassRunner.run(UnitilsJUnit4TestClassRunner.java:67) 
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 
Caused by: java.lang.NullPointerException 
    at java.lang.String.startsWith(String.java:1385) 
    at java.lang.String.startsWith(String.java:1414) 
    at org.unitils.core.dbsupport.MySqlDbSupport.toCorrectCaseIdentifier(MySqlDbSupport.java:189) 
    at org.unitils.core.dbsupport.DbSupport.init(DbSupport.java:97) 
    at org.unitils.core.dbsupport.DbSupportFactory.getDbSupport(DbSupportFactory.java:77) 
    at org.unitils.core.dbsupport.DbSupportFactory.getDefaultDbSupport(DbSupportFactory.java:56) 
    at org.unitils.dbunit.DbUnitModule.getDefaultDbSupport(DbUnitModule.java:755) 
    at org.unitils.dbunit.DbUnitModule.getDataSetFactory(DbUnitModule.java:725) 
    at org.unitils.dbunit.DbUnitModule.getDataSetFactory(DbUnitModule.java:713) 
    at org.unitils.dbunit.DbUnitModule.getDataSet(DbUnitModule.java:441) 
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:261) 
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:187) 
    ... 21 more 

我unitils-local.propreties:

database.userName=root 
database.password=111111 
database.storedIndentifierCase.mysql=mixed_case 
dbUnit.datasetresolver.prefixWithPackageName=false 
database.identifierQuoteString.mysql=none 
database.schemaNames=TEST 
database.dialect=mysql 
database.driverClassName=com.mysql.jdbc.Driver 

我unitils.properties:

# Name or path of the user specific properties file. This file should contain the necessary parameters to connect to the 
# developer's own unit test schema. It is recommended to override the name of this file in the project specific properties 
# file, to include the name of the project. The system will try to find this file in the classpath, the user home folder 
# (recommended) or the local filesystem. 
unitils.configuration.localFileName=unitils-local.properties 

# Properties for the PropertiesDataSourceFactory 
database.driverClassName=com.mysql.jdbc.Driver 
database.url=jdbc:mysql://localhost:3306/test 

database.schemaNames=test 
# This property specifies the underlying DBMS implementation. Supported values are 'oracle', 'db2', 'mysql' and 'hsqldb'. 
# The value of this property defines which vendor specific implementations of DbSupport and ConstraintsDisabler are chosen. 
dbUnit.datasetresolver.prefixWithPackageName=false 

我的數據集選擇:

<?xml version="1.0" encoding="UTF-8"?> 
<dataset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <CLIENT ID="1" CLIENT_NAME="clientName" CLIENT_LAST_NAME="clientLastName" 
      EMAIL="email" ADDRESS="address" PASSWORD="password" 
      PHONE="phone" SECOND_PHONE="secondPhone" THIRD_PHONE="thirdPhone" CREATE_DATE="2015-10-05 08:35:25"/> 
    <CLIENT_GRANT ID="1" ID_CLIENT="1" ADMIN="0" MODERATOR="0" ACTIVE="1"/> 
</dataset> 

而且我測試的DAO類,我試圖測試的某些部分:

@Transactional(TransactionMode.ROLLBACK) 
@DataSet("ClientDaoImplTest.xml") 
public class ClientDaoImplTest extends UnitilsJUnit4 { 
    @TestDataSource 
    DataSource dataSource; 

    ClientDaoImpl clientDao = null; 
    ClientGrantDaoImpl clientGrantDao = null; 

    @Before 
    public void init() { 
     clientDao = new ClientDaoImpl(dataSource); 
     clientGrantDao = new ClientGrantDaoImpl(dataSource); 
     TransactionHandlerImpl.setDataSource(dataSource); 
     clientDao.setCurrentLocalConnection(ConnectionHolder.getLocalConnection()); 
     clientGrantDao.setCurrentLocalConnection(ConnectionHolder.getLocalConnection()); 
    } 

    @After 
    public void destroy() { 
     clientDao = null; 
     clientGrantDao = null; 
    } 

    @Test 
    public void testAddNew() { 
     final User user = new User(); 
     user.setEmail("email"); 
     user.setAddress("address"); 
     user.setPassword("password"); 
     user.setClientName("clientName"); 
     user.setClientLastName("clientLastName"); 
     user.setPhone("phone"); 
     final ClientGrant clientGrant = user.getClientGrant(); 
     clientGrant.setClientId(user.getId()); 
     clientGrant.setActive(true); 
     user.setClientGrant(clientGrant); 
     executeTest(new Transaction<Long>() { 
      @Override 
      public void doTransaction() throws Exception { 
       Long clientId = clientDao.addNew(user); 
       user.setId(clientId); 
       clientGrantDao.addNew(user.getClientGrant()); 
       assertTrue(assertClient(clientDao.get(clientId), user)); 
      } 
     }); 
    } 

我知道有毛病我的數據庫選項。 你能幫我找到解決這個問題的方法嗎? 謝謝。

UPDATE: 來自:

database.identifierQuoteString.mysql=none 

到:

database.identifierQuoteString.mysql=auto 

一個有一個新的異常:

org.unitils.core.UnitilsException: Error inserting test data from DbUnit dataset for method public void com.jean.taxi.daoImpl.ClientDaoImplTest.testAddNew() 
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:190) 
    at org.unitils.dbunit.DbUnitModule$DbUnitListener.beforeTestSetUp(DbUnitModule.java:791) 
    at org.unitils.core.Unitils$UnitilsTestListener.beforeTestSetUp(Unitils.java:273) 
    at org.unitils.UnitilsJUnit4TestClassRunner$TestListenerInvokingMethodRoadie.runBeforesThenTestThenAfters(UnitilsJUnit4TestClassRunner.java:181) 
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87) 
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50) 
    at org.unitils.UnitilsJUnit4TestClassRunner.invokeTestMethod(UnitilsJUnit4TestClassRunner.java:95) 
    at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:59) 
    at org.unitils.UnitilsJUnit4TestClassRunner.access$000(UnitilsJUnit4TestClassRunner.java:42) 
    at org.unitils.UnitilsJUnit4TestClassRunner$1.run(UnitilsJUnit4TestClassRunner.java:60) 
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34) 
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) 
    at org.unitils.UnitilsJUnit4TestClassRunner.run(UnitilsJUnit4TestClassRunner.java:67) 
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137) 
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) 
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) 
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 
Caused by: org.unitils.core.UnitilsException: Error while executing DataSetLoadStrategy 
    at org.unitils.dbunit.datasetloadstrategy.impl.BaseDataSetLoadStrategy.execute(BaseDataSetLoadStrategy.java:46) 
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:342) 
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:268) 
    at org.unitils.dbunit.DbUnitModule.insertDataSet(DbUnitModule.java:187) 
    ... 21 more 
Caused by: org.dbunit.dataset.NoSuchColumnException: client.ID - (Non-uppercase input column: ID) in ColumnNameToIndexes cache map. Note that the map's column names are NOT case sensitive. 
    at org.dbunit.dataset.AbstractTableMetaData.getColumnIndex(AbstractTableMetaData.java:117) 
    at org.dbunit.operation.AbstractOperation.getOperationMetaData(AbstractOperation.java:89) 
    at org.dbunit.operation.AbstractBatchOperation.execute(AbstractBatchOperation.java:143) 
    at org.dbunit.operation.CompositeOperation.execute(CompositeOperation.java:79) 
    at org.unitils.dbunit.datasetloadstrategy.impl.CleanInsertLoadStrategy.doExecute(CleanInsertLoadStrategy.java:45) 
    at org.unitils.dbunit.datasetloadstrategy.impl.BaseDataSetLoadStrategy.execute(BaseDataSetLoadStrategy.java:44) 
    ... 24 more 
改變參數在我unitils-local.properties後

也許有一些新變種我對這個問題的想法?謝謝。

+1

你正在使用哪個版本的Unitils?這個異常消息向我暗示了Unitils的核心模塊和dbunit模塊之間的差異。 –

+0

嗨盧克。我正在使用Unitils版本3.4.2。 –

+1

我看到你已經更新了你的問題並更換了堆棧跟蹤,所以我的評論不再適合你的問題。爲了可能與您有相同問題的其他人的利益,您是如何解決這個問題的? –

回答

3

我要說的是,問題就在這裏:

database.identifierQuoteString.mysql=none 

嘗試將其設置爲替代以下幾點:

database.identifierQuoteString.mysql=auto 

最終,類MySqlDbSupport有一個錯誤在裏面。如果屬性文件中的database.identifierQuoteString.mysql屬性設置爲none,則類DbSupport中名爲identifierQuoteString的專用字段將設置爲空。 MySqlDbSupport中的toCorrectCaseIdentifier方法獲取此字段的值,但忘記在將它傳遞到String.startsWith之前進行空值檢查。因此我們得到一個NullPointerException。

使用auto要求數據庫使用標識符引用字符串。我不明白你爲什麼要使用除此之外的任何東西。

+0

Hi Luke)你是唯一一個試圖提供幫助的人。謝謝。我在unitils-local.properties中使用了你的建議。 我已經更新了我的問題,如果你有一些時間只是看問題的最後部分。也許你對這個問題有所瞭解。 –

+2

@ davakin111:說實話,對於Unitils(我從來沒有用過它)我沒有太多的瞭解,除了它似乎在2011年被放棄了。我根據我的答案閱讀了源代碼Unitils的代碼。您在最近編輯中提到的例外來自DbUnit,我還沒有使用它。對不起,我不認爲我可以在這裏幫助你。 –

+0

感謝您的回覆。沒關係:) 您是否知道一些用於數據庫測試的框架,與Unitils非常相似? –

2

當使用MySQL數據庫的單元時,我遇到了同樣的問題。 解決的辦法是配置MySQL的元數據處理程序:

org.dbunit.database.IMetadataHandler.implClassName=org.dbunit.ext.mysql.MySqlMetadataHandler 

我知道這個問題是老unitils不再保持,但它可以幫助別人。

+0

非常感謝!在過去的2天裏,我花了很多時間在這個問題上! –

+0

很高興聽到它適合你。 –