我已经开始测试,现在我想使用
@After
、@Before
和 @Test
,但我的应用程序仅运行 @Before
方法并在控制台上提供输出
之前
但是,如果我删除
@After
和 @Before
它会运行@Test。我的代码在这里:
public class TestPractise extends AbstractTransactionalDataSourceSpringContextTests{
@Before
public void runBare(){
System.out.println("before");
}
@Test
public void testingMethod(){
System.out.println("testing");
}
@After
public void setDirty(){
System.out.println("after");
}
}
为什么
@After
、@Test
和 @before
不能同时工作?
使用
@BeforeEach
代替 @Before
,使用 @AfterEach
代替 @After
。
AbstractTransactionalDataSourceSpringContextTests
类强制使用旧的JUnit 3.x语法,这意味着任何JUnit 4注释都不起作用。
你的方法
runBare()
被执行不是因为@Before
注解,而是因为它被命名为runBare()
,这是ConditionalTestCase
和JUnitTestCase
类提供的方法。
所以你有2个解决方案:
AbstractTransactionalDataSourceSpringContextTests
的继承,但使用 onSetUp
和 onTearDown
方法而不是 @Before
和 @After
方法。检查您是否使用 Junit4,因为从 Junit5 开始,@Before/@After 现在是 @BeforeEach/@AfterEach,类似的 @BeforeClass/@AfterClass 是 @AfterAll/@BeforeAll。
它应该可以工作...但是由于您正在使用 spring 框架并且 JUnit 4 是几年前引入的,我建议您使用注释而不是继承。
所以,用
@RunWith(SpringJUnit4ClassRunner.class)
来注释你的课程。删除extends AbstractTransactionalDataSourceSpringContextTests
。
不要忘记使 @Before 和 @After 方法static
现在应该可以了。
即使您想扩展 Spring 抽象测试类,至少要注意其中一些已被弃用。例如,类
AbstractTransactionalDataSourceSpringContextTests
已被弃用。
@BeforeAll
如果您使用较新的 JUnit Jupiter(Java 8 及以上版本),您需要将
@Before
替换为 @BeforeAll
。
此外,您需要使用
@TestInstance(Lifecycle.PER_CLASS)
注释您的测试类,或者将 @BeforeAll
方法设置为 static
。 这是一个例子:
@TestInstance(Lifecycle.PER_CLASS)
class MyTestClass {
MyHeavyResource sharedResource;
@BeforeAll
void init() {
System.out.println("init");
sharedResource = new MyHeavyResource(1234);
}
@Test
void myTest() {
System.out.println("myTest");
sharedResource.methodUnderTest();
}
}
Lifecycle.PER_CLASS
JUnit 5 对此更加严格(要求
static
或 Lifecycle.PER_CLASS
)的可能原因是它希望测试作者承认在 @BeforeAll
方法中初始化的任何资源实例将真正在每个资源实例之间共享班级内的单独单元测试方法。 这可能会损害它们的隔离性,例如,如果上面示例中的 sharedResource
不是无状态/幂等的。
如果
sharedResource
无法安全共享(或者如果它相当轻量级),则应使用 init
注释 @BeforeEach
方法,这将在执行类中的每个单独测试之前创建一个新实例。
TestInstance
的Javadoc解释了如何使用Lifecycle.PER_CLASS
实际上强制执行测试类的单个实例;而 JUnit 4 及更早版本的行为相当于 Lifecycle.PER_METHOD
,它为其中包含的每个 @Test
方法创建了一个新的测试类实例。 这会在某种程度上误导作者,认为 @Before
对于每个测试只执行一次。
如果您在 IDE 中使用自动导入,请确保从
@Test
包中导入 @Before
和 org.junit
。
就我而言,我遇到了这个问题,解决方案是更改java访问修饰符,它是私有的。
之前(不工作) @测试 void validate() 抛出异常 {}
(工作后) @测试 public void validate() 抛出异常 {}
@Before
/ @BeforeEach
带注释的 setUp()
方法移至我的单元测试类的构造函数中。@Before
方法我无法解释为什么它解决了问题,但我在一个特定的课程中遇到了这个问题,它确实起到了作用。
就我而言,我的测试课中有多个
@Before
。我将它们合并为一个,问题就消失了。
@Before
fun init() {
Core.IS_TESTING = true
initDatabase()
loadDefinition()
}