org.dbunit.dataset.NoSuchTableException:用户测试

org.dbunit.dataset.NoSuchTableException: UserTest

我找到了一些如何使用 dbunit 的示例 here, from the junitbook2 example

我试过了,效果很好,所以我尝试在我的项目中使用它;我的项目是基于 Maven 的,为了使用数据库,我使用了对外部 jar 的引用,该外部 jar 使用 "ant run" 创建了我的 table 的 bean。 因此,在我的 Maven 项目中,我在我的 src/main/java + 其他 class 中的 src/test/java 中创建了 1 个接口(UserDao),就像书中的示例一样。

UserDao 接口:

import java.sql.SQLException;
import com.mydb.UserTest;
public interface UserDao {

  /**
   * Insert an user in the database.
   * 
   * @param user user to be inserted
   * @return if id the inserted user
   */
  long addUser( UserTest user ) throws SQLException;
  UserTest getUserById( long id ) throws SQLException;
}

AbstractDbUnitTestCase:

import static org.junit.Assert.*;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.sql.Connection;
import java.sql.DriverManager;

import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.ReplacementDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.ext.hsqldb.HsqldbConnection;
import org.junit.AfterClass;
import org.junit.BeforeClass;

public abstract class AbstractDbUnitTestCase {

  protected static UserDaoJdbcImpl dao = new UserDaoJdbcImpl();
  protected static Connection connection;
  protected static HsqldbConnection dbunitConnection;

  @BeforeClass
  public static void setupDatabase() throws Exception {
    Class.forName("com.mysql.jdbc.Driver");
    connection = DriverManager.getConnection("jdbc:mysql://mydb/mydb","user","password");
    if (connection != null) 
        System.out.println("Connected to the database");
    dbunitConnection = new HsqldbConnection(connection,null);
    dao.setConnection(connection);
  }

  @AfterClass
  public static void closeDatabase() throws Exception {
    if ( dbunitConnection != null ) {
      dbunitConnection.close();
      dbunitConnection = null;
    }
  }

  public static IDataSet getDataSet(String name) throws Exception {
    InputStream inputStream = AbstractDbUnitTestCase.class.getResourceAsStream(name);
    assertNotNull("file " + name + " not found in classpath", inputStream );
    Reader reader = new InputStreamReader(inputStream);
    FlatXmlDataSet dataset = new FlatXmlDataSet(reader);
    return dataset;
  }

  public static IDataSet getReplacedDataSet(String name, long id) throws Exception {
    IDataSet originalDataSet = getDataSet(name);
    return getReplacedDataSet(originalDataSet, id);
  }

  public static IDataSet getReplacedDataSet(IDataSet originalDataSet, long id) throws Exception {
    ReplacementDataSet replacementDataSet = new ReplacementDataSet(originalDataSet);
    replacementDataSet.addReplacementObject("[ID]", id);
    replacementDataSet.addReplacementObject("[NULL]", null);
    return replacementDataSet;
  }

}

UserDaoJdbcImplTest --> 测试在哪里

import static org.junit.Assert.*;
import static com.test.EntitiesHelper.*;


import org.dbunit.Assertion;
import org.dbunit.dataset.IDataSet;
import org.dbunit.operation.DatabaseOperation;
import org.junit.Ignore;
import org.junit.Test;

import com.mydb.UserTest;

public class UserDaoJdbcImplTest extends AbstractDbUnitTestCase {

  @Test
  public void testGetUserById() throws Exception {
    IDataSet setupDataSet = getDataSet("/user.xml");
    DatabaseOperation.CLEAN_INSERT.execute(dbunitConnection, setupDataSet);
    UserProvaTest user = dao.getUserById(1);
    assertNotNull( user);
    assertEquals( "Jeffrey", user.getFirstName() );
    assertEquals( "Lebowsky", user.getLastName() );
    assertEquals( "ElDuderino", user.getUsername() );
  }

  @Test @Ignore("fails if run together with others")
  public void testAddUser() throws Exception {
    UserProvaTest user = newUser();
    long id = dao.addUser(user);
    assertTrue(id>0);
    IDataSet expectedDataSet = getDataSet("/user.xml");
    IDataSet actualDataSet = dbunitConnection.createDataSet();
    Assertion.assertEquals( expectedDataSet, actualDataSet );
  }

  @Test
  public void testAddUseIgnoringId() throws Exception {
    IDataSet setupDataSet = getDataSet("/user.xml");
    DatabaseOperation.DELETE_ALL.execute(dbunitConnection, setupDataSet);
    UserProvaTest user = newUser();
    long id = dao.addUser(user);
    assertTrue(id>0);
    IDataSet expectedDataSet = getDataSet("/user.xml");
    IDataSet actualDataSet = dbunitConnection.createDataSet();
    Assertion.assertEqualsIgnoreCols( expectedDataSet, actualDataSet, "users", new String[] { "id" } );
  }

  @Test
  public void testGetUserByIdReplacingIds() throws Exception {
    long id = 42;
    IDataSet setupDataset = getReplacedDataSet("/user-token.xml", id );
    DatabaseOperation.INSERT.execute(dbunitConnection, setupDataset);
    UserProvaTest user = dao.getUserById(id);
    assertUser(user);
  }

  @Test
  public void testAddUserReplacingIds() throws Exception {
    IDataSet setupDataSet = getDataSet("/user-token.xml");
    DatabaseOperation.DELETE_ALL.execute(dbunitConnection, setupDataSet);
    UserProvaTest user = newUser();
    long id = dao.addUser(user);
    assertTrue(id>0);
    IDataSet expectedDataSet = getReplacedDataSet(setupDataSet, id );
    IDataSet actualDataSet = dbunitConnection.createDataSet();
    Assertion.assertEquals( expectedDataSet, actualDataSet );
  }

}

我的 Bean UserTest 是这样创建的:

@Entity (name="mydb_UserTest")@Table(name="UserTest"
    ,catalog="mydb" )

和 user.xml 文件:

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
  <mydb_UserTest id="1" username="ElDuderino" first_name="Jeffrey" last_name="Lebowsky" />
</dataset>

但是当我尝试执行测试时出现此错误:

testGetUserById(com.test.UserDaoJdbcImplTest) Time elapsed: 0.176 sec <<< ERROR! org.dbunit.dataset.NoSuchTableException: UserTest

我看到了:

  1. 数据库连接正确
  2. 但无论我在 user.xml 文件中写入什么,例如 User1111Test 而不是UserTest,报错是一样的(like org.dbunit.dataset.NoSuchTableException: User1111Test);我也尝试使用 schema.UserTest,建议使用 但错误是相同的 NoSuchTableException: schema.UserTest.
  3. 错误在这一点:

    DatabaseOperation.CLEAN_INSERT.execute(dbunitConnection, setupDataSet);

我做错了什么?

你必须添加 FEATURE_QUALIFIED_TABLE_NAMES 属性:

DatabaseConfig config = dBConn.getConfig();
config.setProperty(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);

将它放在您的 setupDatabase 方法中。

在您的 dataset 中,您必须添加架构名称:

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
 <SCHEMA.USERTEST ID="1" USERNAME="ELDUDERINO" FIRST_NAME="JEFFREY" LAST_NAME="LEBOWSKY" />
</dataset>

注意大写的数据集。

希望这对您有所帮助。

基于此信息:

@Entity (name="mydb_UserTest")@Table(name="UserTest"
    ,catalog="mydb" )

正确的 dbUnit 文件 table 名称是:

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
  <mydb.UserTest id="1" username="ElDuderino" first_name="Jeffrey" last_name="Lebowsky" />
</dataset>

如果它是数据库用户的默认模式(通常当模式名称与用户名匹配时),则不带模式名称:

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
  <UserTest id="1" username="ElDuderino" first_name="Jeffrey" last_name="Lebowsky" />
</dataset>

终于找到答案了...

我在数据库中将我的 table 名称从 UserTest 更改为 USERTEST,并且我使用了这个 user.xml:

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
  <USERTEST id="1" username="ElDuderino" first_name="Jeffrey" last_name="Lebowsky" />
</dataset>

我认为,就我而言,没有其他选择,因为 2 个属性:

config.setProperty(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, true);
config.setProperty(DatabaseConfig.FEATURE_CASE_SENSITIVE_TABLE_NAMES, true);

Return 这个信息,所以它们不起作用:

[main] INFO org.dbunit.database.DatabaseConfig - Unknown property 'http://www.dbunit.org/features/qualifiedTableNames'. Cannot validate the type of the object to be set. Please notify a developer to update the list of properties.  
[main] INFO org.dbunit.database.DatabaseConfig - Unknown property 'http://www.dbunit.org/features/caseSensitiveTableNames'. Cannot validate the type of the object to be set. Please notify a developer to update the list of properties.

更新: 避免 FEATURE_QUALIFIED_TABLE_NAMES 的 info/error 的解决方案是使用

dbunitConnection.getConfig().setFeature(DatabaseConfig.FEATURE_QUALIFIED_TABLE_NAMES, 真); dbunitConnection.getConfig().setFeature(DatabaseConfig.FEATURE_CASE_SENSITIVE_TABLE_NAMES, 真);

而不是setProperty;并将 HsqldbConnection dbunitConnection 更改为 MySqlConnection dbunitConnection.