我有一個抽象的測試用例,使用測試接口的Theories
runner。接口的每個實現都具有測試用例的具體實現,其中一個實現使用Postgres。我想讓測試用例只在連接到Postgres數據庫時纔會運行,否則將被忽略。如何在使用Theories時在jUnit中獲得條件執行?
我不能使用Assume
,因爲如果理論的所有數據點都不符合他們的假設,則Theories
測試運行器將失敗。
我正在測試一個本質上是一個簡單文件系統的ResourceStore。它需要路徑並返回Resource對象,這些對象可以由文件系統支持,或者通過Postgres之類的其他東西來支持。我使用Theories來測試返回的資源遵循某些規則,以便實現彼此一致。
的基類看起來是這樣的(進口和最具體的測試修剪)
/**
* JUnit Theory test class for Resource invariants. Subclasses should provide representative
* DataPoints to test.
*
*/
@RunWith(Theories.class)
public abstract class ResourceTheoryTest {
@Rule
public ExpectedException exception = ExpectedException.none();
protected abstract Resource getResource(String path) throws Exception;
@Theory
public void theoryNotNull(String path) throws Exception {
Resource res = getResource(path);
assertThat(res, notNullValue());
}
@Theory
public void theoryExtantHaveDate(String path) throws Exception {
Resource res = getResource(path);
assumeThat(res, defined());
long result = res.lastmodified();
assertThat(result, notNullValue());
}
}
的基於文件系統的實現創建一個臨時目錄,有一些文件對其進行設置,然後點擊商店爲測試路徑,一些現有的,一些沒有。
public class FileSystemResourceTheoryTest extends ResourceTheoryTest {
FileSystemResourceStore store;
@Rule
public TemporaryFolder folder= new TemporaryFolder();
@DataPoints
public static String[] testPaths() {
return new String[]{"FileA","FileB", "DirC", "DirC/FileD", "DirE", "UndefF", "DirC/UndefF", "DirE/UndefF", "DirE/UndefG/UndefH/UndefI"};
}
@Override
protected Resource getResource(String path) throws Exception{
return store.get(path);
}
@Before
public void setUp() throws Exception {
folder.newFile("FileA");
folder.newFile("FileB");
File c = folder.newFolder("DirC");
(new File(c, "FileD")).createNewFile();
folder.newFolder("DirE");
store = new FileSystemResourceStore(folder.getRoot());
}
}
基於JDBC模塊具有基於所述第一另一抽象測試的情況下,其使用TestSupport委託來抽象在連接和設置的測試環境的方言差異。同樣的支持類也用於其他非理論測試。
public abstract class AbstractJDBCResourceTheoryTest extends ResourceTheoryTest {
DatabaseTestSupport support;
@DataPoints
public static String[] testPaths() {
return new String[]{"FileA","FileB", "DirC", "DirC/FileD", "DirE", "UndefF", "DirC/UndefF", "DirE/UndefF"/*, "DirE/UndefG/UndefH/UndefI"*/};
}
protected JDBCResourceStoreProperties mockConfig(boolean enabled, boolean init) {
JDBCResourceStoreProperties config = createMock(JDBCResourceStoreProperties.class);
expect(config.isInitDb()).andStubReturn(init);
expect(config.isEnabled()).andStubReturn(enabled);
expect(config.isImport()).andStubReturn(init);
support.stubConfig(config);
return config;
}
protected DataSource testDataSource() throws Exception {
return support.getDataSource();
}
public AbstractJDBCResourceTheoryTest() {
super();
}
protected void standardData() throws Exception {
support.initialize();
support.addFile("FileA", 0, "FileA Contents".getBytes());
support.addFile("FileB", 0, "FileB Contents".getBytes());
int c = support.addDir("DirC", 0);
support.addFile("FileD", c, "FileD Contents".getBytes());
support.addDir("DirE", 0);
}
Integer getInt(ResultSet rs, String column) throws Exception {
int i = rs.getInt(column);
if(rs.wasNull()) return null;
return i;
}
@After
public void cleanUp() throws Exception {
support.close();
}
}
Postgres測試用例只是插入Postgres測試支持模塊並使用它來初始化測試框架和被測試的資源存儲。它目前連接到每個測試的每個數據庫的數據庫,但我打算解決這個問題。
public class PostgresJDBCResourceTheoryTest extends AbstractJDBCResourceTheoryTest {
JDBCResourceStore store;
@Override
protected Resource getResource(String path) throws Exception{
return store.get(path);
}
@Before
public void setUp() throws Exception {
support = new PostgresTestSupport();
standardData();
JDBCResourceStoreProperties config = mockConfig(true, false);
replay(config);
store = new JDBCResourceStore(support.getDataSource(), config);
}
}
還有一個H2實現的測試,其工作方式與使用內存H2數據庫相同。
正如我在我的回答中演示的,您的@ DataPoints方法必須是您檢查連接狀態的點。鑑於你的更新代碼,你需要有一個永久有效的資源來測試。 你想要做的正確解決方案是實現你自己的跑步者。我說的是正確的,因爲這就是你如何做到這一點,而不是試圖對抗JUnit的架構。但是這可能比你想要解決的更麻煩。 – ngreen