@After、@before 不在测试用例中工作

问题描述 投票:0回答:9

我已经开始测试,现在我想使用

@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
不能同时工作?

java junit testcase
9个回答
76
投票

使用

@BeforeEach
代替
@Before
,使用
@AfterEach
代替
@After


21
投票

AbstractTransactionalDataSourceSpringContextTests
类强制使用旧的JUnit 3.x语法,这意味着任何JUnit 4注释都不起作用。

你的方法

runBare()
被执行不是因为
@Before
注解,而是因为它被命名为
runBare()
,这是
ConditionalTestCase
和JUnit
TestCase
类提供的方法。

所以你有2个解决方案:

  • 使用 AlexR 答案来使用 JUnit 4 测试和 Spring;
  • 保留对
    AbstractTransactionalDataSourceSpringContextTests
    的继承,但使用
    onSetUp
    onTearDown
    方法而不是
    @Before
    @After
    方法。

20
投票

检查您是否使用 Junit4,因为从 Junit5 开始,@Before/@After 现在是 @BeforeEach/@AfterEach,类似的 @BeforeClass/@AfterClass 是 @AfterAll/@BeforeAll。


7
投票

它应该可以工作...但是由于您正在使用 spring 框架并且 JUnit 4 是几年前引入的,我建议您使用注释而不是继承。

所以,用

@RunWith(SpringJUnit4ClassRunner.class)
来注释你的课程。删除
extends AbstractTransactionalDataSourceSpringContextTests

不要忘记使 @Before 和 @After 方法static

现在应该可以了。

即使您想扩展 Spring 抽象测试类,至少要注意其中一些已被弃用。例如,类

AbstractTransactionalDataSourceSpringContextTests
已被弃用。


6
投票

JUnit Jupiter,又名“JUnit 5”:使用
@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
对于每个测试只执行一次。


3
投票

如果您在 IDE 中使用自动导入,请确保从

@Test
包中导入
@Before
org.junit


0
投票

就我而言,我遇到了这个问题,解决方案是更改java访问修饰符,它是私有的。

之前(不工作) @测试 void validate() 抛出异常 {}

(工作后) @测试 public void validate() 抛出异常 {}


0
投票
  • 就我而言,我只是将内容从
    @Before
    /
    @BeforeEach
    带注释的
    setUp()
    方法移至我的单元测试类的构造函数中。
  • 根据这个线程使用构造函数“等同于”
    @Before
    方法

我无法解释为什么它解决了问题,但我在一个特定的课程中遇到了这个问题,它确实起到了作用。


0
投票

就我而言,我的测试课中有多个

@Before
。我将它们合并为一个,问题就消失了。

@Before
fun init() {
    Core.IS_TESTING = true

    initDatabase()
    loadDefinition()
}
© www.soinside.com 2019 - 2024. All rights reserved.