私は 2 つの jUnit テスト クラスを持っています。1 つは自分のItemService
クラスをテストするため、もう 1 つは自分のクラスをテストするためLocationService
です。ItemService
テストを実行すると、合格します。テストを実行すると、次のLocationService
エラーで失敗します。
原因: java.sql.SQLException: org.hsqldb.jdbc.Util.throwError(不明なソース) のステートメント [SELECT COUNT(*) FROM locations] にテーブルが見つかりませんorg.hsqldb.jdbc.jdbcConnection.prepareStatement で (不明なソース)
データベースにロードされているスキーマ ファイルがあり、最初に作成されたテーブルがItemService
使用されます。同じスキーマ ファイル内にあるにもかかわらず、テストで使用するlocations
テーブルLocationService
が作成されない可能性があります。
これは私の test-context.xml ファイルにあります:
<jdbc:embedded-database
id="myTestDB"
type="HSQL">
<jdbc:script
location="classpath:/test-ddl.sql" />
<jdbc:script
location="classpath:/test-data.sql" />
</jdbc:embedded-database>
<bean
id="dataSourceTest"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property
name="driverClassName"
value="org.hsqldb.jdbcDriver" />
<property
name="url"
value="jdbc:hsqldb:mem:myTestDB" />
<property
name="username"
value="sa" />
<property
name="password"
value="" />
</bean>
テーブルが見つからないというエラーが発生せずに 1 つのテストが成功し、データベースに存在しないitems
ために別のテストが失敗する理由がわかりません。locations
HSQLDB と Hibernate の使用に関する他の投稿を見ましたが、私は Hibernate を使用していません。これらは、test-ddl.sql ファイルで作成しているテーブルです。
CREATE MEMORY TABLE "ITEMS" (
"ID" INTEGER NOT NULL IDENTITY,
"NAME" VARCHAR(50) NOT NULL,
"LOCATION_ID" INTEGER NOT NULL,
"ITEM_TYPE_ID" INTEGER NOT NULL
);
CREATE MEMORY TABLE "ITEM_TYPES" (
"ID" INTEGER NOT NULL IDENTITY,
"NAME" VARCHAR(50) NOT NULL,
"ICON_CLASS" VARCHAR(50)
);
CREATE CACHED TABLE "LOCATIONS" (
"ID" INTEGER NOT NULL IDENTITY,
"NAME" VARCHAR(50) NOT NULL,
"PHOTO" LONGVARBINARY,
"PHOTO_CONTENT_TYPE" VARCHAR(60),
"PHOTO_WIDTH" INTEGER,
"PHOTO_HEIGHT" INTEGER
);
また、テーブル作成ステートメントの後にいくつかUNIQUE
のFOREIGN KEY
制約をスキーマに設定しましたが、何かを作成できなかったかどうかは確かにわかります。HSQLDB 1.8.1.3 JAR を使用しています。locations
クエリを実行できないのに、クエリを実行できるのはなぜitems
ですか?
編集:この質問に基づいて考えた場合、大文字と小文字の区別の問題がある可能性がありますが、LOCATIONS
テーブルから SELECT しようとしても失敗します:
原因: java.sql.SQLException: ステートメントにテーブルが見つかりません [SELECT COUNT(*) FROM LOCATIONS]
編集:私の魔法の作業ItemService
テスト:
@ContextConfiguration("/test-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager = "transactionManager")
public class ItemServiceTest {
private EmbeddedDatabase _db;
private ItemService _svc;
@Before
public void setUp() throws Exception {
_db = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL)
.setName("myTestDB").build();
assertThat(_db, is(notNullValue()));
_svc = new ItemService();
_svc.setDataSource(_db);
}
@After
public void tearDown() throws Exception {
_db.shutdown();
}
@Test
public void testGetCount() {
assertThat(_svc.getCount(), is(not(0)));
}
}
私の失敗したLocationService
テストはまったく同じですが、LocationService
代わりにItemService
. getCount()
メソッドは と の両方に表示されLocationService
ますItemService
。
public int getCount() {
String sql = "SELECT COUNT(*) FROM " + TABLE_NAME;
return _jdbcTmpl.queryForInt(sql, (Map<String, Object>)null);
}
のTABLE_NAME
間で異なりますItemService
:
public static final String TABLE_NAME = "ITEMS";
とLocationService
:
public static final String TABLE_NAME = "LOCATIONS";
と の両方ItemService
にLocationService
次のものがあります。
private NamedParameterJdbcTemplate _jdbcTmpl;
@Resource(name = "dataSource")
public void setDataSource(DataSource dataSource) {
_jdbcTmpl = new NamedParameterJdbcTemplate(dataSource);
}
編集:問題への新たなひねり。私のLocationService
テストでは、まだ具体化されていない他のテスト方法がいくつかありました。
@Test
public void testFind() {
fail("Not yet implemented");
}
私のItemService
テストでは、唯一の@Test
メソッドはtestGetCount
合格でした。testFind
上記をテストクラスに追加すると、テストクラスと同じようにItemService
突然testGetCount
失敗しますLocationService
。
原因: java.sql.SQLException: ステートメントにテーブルが見つかりません [SELECT COUNT(*) FROM ITEMS]
編集:static
@BeforeClass
/@AfterClass
メソッドを使用していないとき (つまり、テストでテーブルが見つからなかったとき) にデバッガーをステップスルーすると、次のコンソール出力に気付きました。
2012 年 4 月 10 日 10:22:44 AM org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory initDatabase INFO: 組み込みデータベース 'myTestDB' を作成しています 2012 年 4 月 10 日 10:22:44 AM org.springframework.jdbc.datasource.init. ResourceDatabasePopulator executeSqlScript INFO: クラスパス リソースから SQL スクリプトを実行しています [test-ddl.sql] 2012 年 4 月 10 日 10:22:44 AM org.springframework.jdbc.datasource.init.ResourceDatabasePopulator executeSqlScript INFO: クラスパス リソースから SQL スクリプトを実行しました[test-ddl.sql] で 30 ミリ秒。2012 年 4 月 10 日 10:22:44 AM org.springframework.jdbc.datasource.init.ResourceDatabasePopulator executeSqlScript INFO: クラスパス リソースから SQL スクリプトを実行 [test-data.sql] 2012 年 4 月 10 日 10:22:44 AM org. springframework.jdbc.datasource.init.ResourceDatabasePopulator executeSqlScript 情報: クラスパス リソース [test-data.sql] からの SQL スクリプトの実行が 46 ミリ秒で完了しました。2012 年 4 月 10 日 10:22:55 AM org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseFactory initDatabase INFO: 組み込みデータベース 'myTestDB' を作成しています 2012 年 4 月 10 日 10:23:08 AM org.springframework.jdbc.datasource.embedded. EmbeddedDatabaseFactory initDatabase INFO: 組み込みデータベース 'myTestDB' を作成しています
したがって、データベースをセットアップし、最初に create-tables および populate-tables スクリプトを実行するように見えます。その後、再初期_db
化すると、スクリプトは再度実行されません。したがって、後続のテスト メソッド用のテーブルは存在しません。したがって、Spring にこれらのスクリプトを毎回強制的に再実行させる方法を見つけることができれば、セットアップ メソッドとティアダウン メソッドにインスタンス メソッドを@Before
使用する方法に戻ることができます。@After