2015-11-02 146 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

很高兴听到它适合你。 –