@beforeclass和继承 - 执行顺序
-
22-09-2019 - |
题
我有一个抽象的基类,我将其用作单元测试的基础(TestNG 5.10)。在此课程中,我初始化了测试的整个环境,设置数据库映射等。此抽象类具有一个带有一个方法的方法 @BeforeClass
进行初始化的注释。
接下来,我使用我拥有的特定课程扩展该课程 @Test
方法以及 @BeforeClass
方法。这些方法对环境进行特定于类的初始化(例如将一些记录放入数据库中)。
我如何执行特定订单 @BeforeClass
注释方法?我需要从抽象基类中执行扩展类的基础类别。
例子:
abstract class A {
@BeforeClass
doInitialization() {...}
}
class B extends A {
@BeforeClass
doSpecificInitialization() {...}
@Test
doTests() {...}
}
预期订单:
A.doInitialization
B.doSpecificInitialization
B.doTests
实际订单:
B.doSpecificInitialization // <- crashes, as the base init is missing
(A.doInitialization // <---not executed
B.doTests) // <-/
解决方案
不要放 @BeforeClass
在 abstract
班级。从每个子类调用它。
abstract class A {
void doInitialization() {}
}
class B extends A {
@BeforeClass
void doSpecificInitialization() {
super.doInitialization();
}
@Test
void doTests() {}
}
似乎Testng有 @BeforeClass(dependsOnMethods={"doInitialization"})
- 试试看。
其他提示
编辑: 下面的答案是 朱尼特, ,但是无论如何我都会把它留在这里,因为它可能会有所帮助。
根据 Junit API: :“超类的@beforeclass方法将在当前类之前运行。”
我对此进行了测试,似乎对我有用。
但是,正如@odys在下面提到的那样,对于Junit,您需要拥有 两种命名的方法不同 虽然这样做,但由于父母会被遮蔽,因此只会导致子类方法正在运行。
我添加了 public
在抽象类和testng(6.0.1)之前执行了doinitialization() doTests
. 。 Testng不执行 doInitialization()
如果我删除 public
来自A级A。
public abstract class A {
@BeforeClass
doInitialization() {...}
}
class B extends A {
@Test
doTests() {...}
}
我只是用5.11尝试了您的示例,然后首先调用了基类的@beforeclass。
您可以发布testng.xml文件吗?也许您在那里指定A和B,而仅需B。
请随时跟进Testng-users邮寄列表,我们可以仔细研究您的问题。
- 塞德里克
我只是经历了这一点,并找到了一种实现这一目标的方法。只是使用 alwaysRun
上 @BeforeClass
或者 @BeforeMethod
在抽象课程中,按照您的期望工作。
public class AbstractTestClass {
@BeforeClass(alwaysRun = true)
public void generalBeforeClass() {
// do stuff
specificBeforeClass();
}
}
当我逃跑时: junitcore.runclasses(testclass.class);它将在孩子之前正确执行父母(您不需要 super.setupbeforeclass();)如果您从Eclipse运行它:由于某种原因,它无法运行基类。工作的工作:明确致电基类:((basetest.setupbeforeclass();)如果您从应用程序运行它,则可能需要在基类中有一个标志,以确定它是否已经设置。因此,它仅在您通过两种可能的方法运行(例如来自Eclipse的个人测试,以及通过ANT进行构建版本)运行一次。
这似乎是Eclipse或至少意外结果的错误。
为junit:正如@fortega所提到的:根据Junit API的说法:“ @beforeclass的超类方法将在当前班级之前运行。”
但小心点 不要命名两种使用相同名称的方法. 。由于在这种情况下,父母将隐藏父级的方法。 资源.
如何使您的@beforeclass方法调用一个空的特定beforeclass()方法,该方法可能会被类似子类覆盖或可能不会覆盖:
public class AbstractTestClass {
@BeforeClass
public void generalBeforeClass() {
// do stuff
specificBeforeClass();
}
protected void specificBeforeClass() {}
}
public class SpecificTest {
@Override
protected void specificBeforeClass() {
// Do specific stuff
}
// Tests
}
dependsOnMethod
可以使用。
例如在春季的情况下(AbstractTestNGSpringContextTests
)
@BeforeClass(alwaysRun = true, dependsOnMethods = "springTestContextPrepareTestInstance")
检查您的导入语句。它应该是
import org.testng.annotations.BeforeClass;
不是
import org.junit.BeforeClass;
您为什么不尝试在超级类中创建一个抽象方法dospecialinit(),从超级类中的beforeclass注释方法中调用。
因此,继承您的班级的开发人员被迫实施此方法。
这里还有另一个简单的解决方案。
我的特殊情况是,我需要在执行超级类中的“ beforeclass”之前从“ beforeclass”中注入模拟服务。
为此 - 只需使用 @ClassRule
在子类中。
例如:
@ClassRule
public static ExternalResource mocksInjector = new ExternalResource() {
@Override
protected void before() {
// inject my mock services here
// Note: this is executed before the parent class @BeforeClass
}
};
我希望这有帮助。这可以有效地执行“反向”顺序的静态设置。
我今天面临类似的问题,唯一的区别是基类不是抽象的
这是我的案子
public class A {
@BeforeClass
private void doInitialization() {...}
}
public class B extends A {
@BeforeClass
private void doSpecificInitialization() {...}
@Test
public void doTests() {...}
}
发生了一个 @BeforeClass
A类的方法从未执行。
- a.doinialization() - >从未默默执行
- B. oppecificinialization()
- b.dotests()
使用隐私修饰符播放我发现Testng 不会执行 一个 @BeforeClass
来自继承类的注释方法 如果从类商中看不到方法
因此,这将起作用:
public class A {
@BeforeClass
private void doInitialization() {...}
}
public class B extends A {
@BeforeClass
//Here a privacy modifier matters -> please make sure your method is public or protected so it will be visible for ancestors
protected void doSpecificInitialization() {...}
@Test
public void doTests() {...}
}
结果,以下发生了:
- a.doinialization()
- B. oppecificinialization()
- b.dotests()
这对我有用 -
abstract class A {
@BeforeClass
doInitialization() {...}
}
class B extends A {
@Override
@BeforeClass
doInitialization() {
//do class specific init
}
@Test
doTests() {...}
}
在我的情况下(junit),我在基类和派生类中具有相同的方法称为setup()。在这种情况下 只要 派生类的方法被调用,我称其为基类方法。
使用继承实现这一目标的更好,更干净的方法可能如下 -
abstract class A {
@BeforeClass
void doInitialization() {}
}
class B extends A {
@Override
@BeforeClass
void doInitialization() {
super.doInitialization();
}
@Test
void doTests() {}
}