- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
为了只创建一次环境并避免继承,我使用 @ClassRule
定义了一个 JUnit Suite 类:
@RunWith(Suite.class)
@Suite.SuiteClasses({
SuiteTest1.class
})
public class JUnitTest {
@ClassRule
private static DockerComposeContainer env = ...
@BeforeClass
public static void init(){
...
}
...
}
还有一个 Test 类在测试方法中使用 env:
public class SuiteTest1 {
@Test
public void method(){
client.query(...);// Executes a query against docker container
}
}
当我通过运行测试套件来执行测试时,一切都按预期进行。但是,当我直接尝试运行(即使使用 IDE)SuiteTest1
测试类时,它会失败,并且不会调用 Suite 中的任何内容(即 @
ClassRule 和 @BeforeClass
)。
关于如何以良好的方式实现 SuiteTest1 单一执行(无需从 SuiteTest1
中调用 JUnitTest
的静态方法)有什么建议吗?
最佳答案
重新表述问题:您需要一个带有 before-all 和 after-all Hook 的 JUnit 套件,它也会在逐个运行测试时运行(例如从 IDE)。
据我所知,JUnit 4 没有为此提供任何开箱即用的功能,但如果您愿意将一些 Spring 第三方 deps( spring-test 和 spring-context )合并到您的项目中,我可以提出一个我一直在使用的解决方法。
本文后续内容的完整代码示例 can be found here .
我们将使用 Spring 上下文来实现初始化和清理。让我们为测试添加一个基类:
@ContextConfiguration(initializers = AbstractTestClass.ContextInitializer.class)
public class AbstractTestClass {
@ClassRule
public final static SpringClassRule springClassRule = new SpringClassRule();
@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
public static class ContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext context) {
System.out.println("Initializing context");
context.addApplicationListener(
(ApplicationListener<ContextClosedEvent>)
contextClosedEvent ->
System.out.println("Closing context"));
}
}
}
注意 SpringClassRule
和SpringMethodRule
JUnit 规则使用 Spring super 能力增强我们的基类(Spring 测试注释处理 - 在本例中为 ContextConfiguration
,但其中还有更多好东西 - 有关详细信息,请参阅 Spring testing reference)。您可以使用 SpringRunner
为此目的,但它是一个不太灵活的解决方案(因此被省略)。
测试类:
public class TestClass1 extends AbstractTestClass {
@Test
public void test() {
System.out.println("TestClass1 test");
}
}
public class TestClass2 extends AbstractTestClass {
@Test
public void test() {
System.out.println("TestClass2 test");
}
}
和测试套件:
@RunWith(Suite.class)
@SuiteClasses({TestClass1.class, TestClass2.class})
public class TestSuite {
}
运行套件时的输出(为了简洁,删除了 Spring 特定的日志):
Initializing context
TestClass1 test
TestClass2 test
Closing context
运行单个测试时的输出(TestClass1
):
Initializing context
TestClass1 test
Closing context
其工作方式是由于 Spring 的上下文缓存。引用文档:
Once the TestContext framework loads an
ApplicationContext
(orWebApplicationContext
) for a test, that context is cached and reused for all subsequent tests that declare the same unique context configuration within the same test suite. To understand how caching works, it is important to understand what is meant by “unique” and “test suite.”
请注意,如果您为层次结构中的任何类(在我们的示例中为 TestClass1
或 TestClass2
)重写上下文配置(例如,使用 ContextConfiguration
添加另一个上下文初始值设定项),您将获得另一个上下文(和另一个初始化)。
您可以在您的上下文中定义 bean。它们将在使用相同上下文的所有测试中共享。这对于在测试套件中共享对象非常有用(根据标签判断,在您的案例中是一个 Testcontainers 容器)。
让我们添加一个 bean:
@ContextConfiguration(initializers = AbstractTestClass.ContextInitializer.class)
public class AbstractTestClass {
@ClassRule
public final static SpringClassRule springClassRule = new SpringClassRule();
@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
public static class ContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext context) {
ADockerContainer aDockerContainer = new ADockerContainer();
aDockerContainer.start();
context.getBeanFactory().registerResolvableDependency(
ADockerContainer.class, aDockerContainer);
context.addApplicationListener(
(ApplicationListener<ContextClosedEvent>)
contextClosedEvent ->
aDockerContainer.stop());
}
}
}
并将其注入(inject)到测试类中:
public class TestClass1 extends AbstractTestClass {
@Autowired
private ADockerContainer aDockerContainer;
@Test
public void test() {
System.out.println("TestClass1 test " + aDockerContainer.getData());
}
}
public class TestClass2 extends AbstractTestClass {
@Autowired
private ADockerContainer aDockerContainer;
@Test
public void test() {
System.out.println("TestClass2 test " + aDockerContainer.getData());
}
}
ADockerContainer
类:
public class ADockerContainer {
private UUID data;
public void start() {
System.out.println("Start container");
data = UUID.randomUUID();
}
public void stop() {
System.out.println("Stop container");
}
public String getData() {
return data.toString();
}
}
(示例)输出:
Start container
TestClass1 test 56ead80b-ec34-4dd6-9c0d-d6f07a4eb0d8
TestClass2 test 56ead80b-ec34-4dd6-9c0d-d6f07a4eb0d8
Stop container
关于java - 从带有 @ClassRule 的 Suite 运行单个测试失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52551735/
我想使用 li 和 ul 制作一个多级下拉列表,以便显示我博客中按年和月排序的所有文章。我希望我的下拉菜单看起来像 Google Blogspot 下拉菜单: 这是我的 CSS 和 HTML 代码 u
我在 Win 7 64 机器上将 CodeBlocks 与 gcc 4.7.2 和 gmp 5.0.5 结合使用。开始使用 gmpxx 后,我看到一个奇怪的段错误,它不会出现在 +、- 等运算符中,但
我正在使用 tern 为使用 CodeMirror 运行的窗口提供一些增强的智能感知,它工作正常,但我遇到了一个问题,我想添加一些自定义“types”,可以这么说,这样下拉列表中它们旁边就有图标了。我
我正在尝试让我的 PC 成为 Android 2.3.4 设备的 USB 主机,以便能够在不需要实际“附件”的情况下开发 API。为此,我需要将 PC 设置为 USB 主机和“设备”(在我的例子中是运
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
我在设置服务器方面几乎是个新手,但遇到了一个问题。我有一个 Ubuntu 16.04 VPS 并安装了 Apache2 和 Tomcat7。我正在为 SSL 使用 LetsEncrypt 和 Cert
我在一个基于谷歌地图的项目上工作了超过 6 个月。我使用的是 Google Maps API V1 及其开发人员 API key 。当我尝试发布应用程序时,我了解到 Google API V1 已被弃
我是 Python 的新手,所以如果我对一些简单的事情感到困惑,请原谅。 我有一个这样的对象: class myObject(object): def __init__(self):
这个问题已经有答案了: How can I access object properties containing special characters? (2 个回答) 已关闭 9 年前。 我正在尝
我有下面的 CSS。我想要的是一种流体/液体(因为缺乏正确的术语)css。我正在为移动设备开发,当我改变模式时 从纵向 View 到陆地 View ,我希望它流畅。现在的图像 在陆地 View 中效
我正在尝试使用可以接受参数的缓存属性装饰器。 我查看了这个实现:http://www.daniweb.com/software-development/python/code/217241/a-cac
这个问题在这里已经有了答案: Understanding slicing (36 个答案) 关闭 6 年前。 以a = [1,2,3,4,5]为例。根据我的直觉,我认为 a[::-1] 与 a[0:
mysqldump -t -u root -p mytestdb mytable --where=datetime LIKE '2014-09%' 这就是我正在做的事情,它会返回: mysqldum
我正在制作销售税计算器,除了总支付金额部分外,其他一切都正常。在我的程序中,我希望能够输入一个数字并获得该项目的税额我还希望能够获得支付的总金额,包括交易中的税金。到目前为止,我编写的代码完成了所有这
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许在 Stack Overflow 上提出有关通用计算硬件和软件的问题。您可以编辑问题,使其成为
我是否必须进行任何额外的设置才能让 apache-airflow 在任务失败时向我发送电子邮件。我的配置文件中有以下内容(与默认值保持不变): [email] email_backend = airf
这个问题在这里已经有了答案: What does the $ symbol do in VBA? (5 个回答) 3年前关闭。 使用返回字符串(如 Left)的内置函数有什么区别吗?或使用与 $ 相同
我有一个用VB6编写的应用程序,我需要使用一个用.NET编写的库。有什么方法可以在我的应用程序上使用该库吗? 谢谢 最佳答案 这取决于。您可以控制.NET库吗? 如果是这样,则可以修改您的库,以便可以
当我创建一个以 ^ 开头的类方法时,我尝试调用它,它给了我一个错误。 class C { method ^test () { "Hi" } } dd C.new.test; Too m
我已经使用 bower 安装了 angularjs 和 materialjs。 凉亭安装 Angular Material 并将“ngMaterial”注入(inject)我的应用程序,但出现此错误。
我是一名优秀的程序员,十分优秀!