gpt4 book ai didi

java - 使用 Theories 时如何在 jUnit 中获得条件执行?

转载 作者:搜寻专家 更新时间:2023-11-01 03:52:26 25 4
gpt4 key购买 nike

我有一个使用 Theories runner 测试接口(interface)的抽象测试用例。接口(interface)的每个实现都有测试用例的具体实现,其中一个实现使用 Postgres。我想让该测试用例仅在与 Postgres 数据库的连接实际可用时运行,否则将被忽略。

我不能使用 Assume,因为如果一个理论的所有数据点都未通过其假设,则 Theories 测试运行程序将失败。

我正在测试一个 ResourceStore,它本质上是一个简单的文件系统。它获取路径并返回 Resource 对象,这些对象可能由文件系统或其他类似 Postgres 的东西支持。我正在使用理论来测试返回的资源是否遵循特定规则,以便实现彼此一致。

基类看起来像这样(导入并修剪了大部分特定测试)

/**
* 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 委托(delegate)来抽象连接和设置测试环境时的方言差异。相同的支持类也用于其他非理论测试。

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 测试支持模块,并使用它来初始化测试框架和被测试的 Resource Store。它目前为每个测试的每个数据点连接到数据库,尽管我计划修复它。

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 数据库。

最佳答案

由于不知道您的代码是什么样子,我做了一堆假设并创建了一个似乎支持您的意图的示例。

import org.junit.experimental.theories.*;

@org.junit.runner.RunWith(Theories.class)
public class TheoryTest {
// this is one possible way to store the setting:
private static ThreadLocal<Boolean> postgresConnected = new ThreadLocal<>();
static interface Under {}
static class Over implements Under {}
static class Through implements Under {}
static { postgresConnected.set(true); } // this logic belongs somewhere else

@DataPoints
public static Under[] underData() {
if (postgresConnected.get())
return new Under[] { new Over(), new Through() };
return new Under[] { new Over() };
}

@Theory
public void testUnder(Under under) {
System.out.println(under.getClass());
org.junit.Assert.assertNotNull(under);
}
}

如果这不能满足您的需求,请发布更多详细信息,我会看看我能想出什么。

关于java - 使用 Theories 时如何在 jUnit 中获得条件执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21998195/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com