@After ,@before not working in testcase
Asked Answered
M

9

50

I have started testing and now i want to use @After, @Before and @Test but my application only runs the @Before method and gives output on console

before

However, if I remove @After and @Before it runs the @Test. My code is here:

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");
    }
}

Why aren't @After, @Test and @before working simultaneously?

Mildred answered 14/5, 2012 at 9:26 Comment(0)
P
21

The AbstractTransactionalDataSourceSpringContextTests class forces the use of the old JUnit 3.x syntax, which means that any of the JUnit 4 annotation will not work.

Your method runBare() is executed not because of the @Before annotation, but because it is named runBare(), which is a method provided by ConditionalTestCase and JUnit TestCase class.

So you have 2 solutions:

  • Use the AlexR answer to use JUnit 4 tests and Spring;
  • Keep your inheritance of AbstractTransactionalDataSourceSpringContextTests, but use the onSetUp and onTearDown methods instead of the @Before and @After methods.
Pamalapamela answered 14/5, 2012 at 14:44 Comment(1)
Got this same problem mixing up JUnit 4 and 5. Check your imports for the annotations and make sure they match.Campanology
D
76

Use @BeforeEach instead of @Before and @AfterEach instead of @After.

Drab answered 25/7, 2018 at 9:39 Comment(5)
Could you add a little bit of an explanation about why and how this solves the problem?Carboniferous
In my case my "@Before" and "@After" code was not running, but it worked when i replaced "@Before" with "@BeforeEach" and "@After" and "@AfterEach".Drab
It's just more specific names working is same. But support (Execution) is depends on Junit version.Drab
dude! I spent hours figuring this out!Cabasset
Just keep in mind this creates alot of wasted execution. BeforeEach resets everything before every test is run. This could be desirable but unnecessary for example, when loading a file for test parameters or one-time file reads for the class.Contuse
P
21

The AbstractTransactionalDataSourceSpringContextTests class forces the use of the old JUnit 3.x syntax, which means that any of the JUnit 4 annotation will not work.

Your method runBare() is executed not because of the @Before annotation, but because it is named runBare(), which is a method provided by ConditionalTestCase and JUnit TestCase class.

So you have 2 solutions:

  • Use the AlexR answer to use JUnit 4 tests and Spring;
  • Keep your inheritance of AbstractTransactionalDataSourceSpringContextTests, but use the onSetUp and onTearDown methods instead of the @Before and @After methods.
Pamalapamela answered 14/5, 2012 at 14:44 Comment(1)
Got this same problem mixing up JUnit 4 and 5. Check your imports for the annotations and make sure they match.Campanology
K
21

Check that you are using Junit4 because from Junit5 onwards @Before/@After is now @BeforeEach/@AfterEach and similarly @BeforeClass/@AfterClass is now @AfterAll/@BeforeAll.

Kaitlinkaitlyn answered 14/7, 2020 at 6:58 Comment(0)
C
7

It should work... But since you are working with spring framework and JUnit 4 was introduced years ago I's suggest you to use annotations instead of inheritance.

So, annotate you class with @RunWith(SpringJUnit4ClassRunner.class). Remove extends AbstractTransactionalDataSourceSpringContextTests.

Don't forget to make the @Before and @After methods static

Now it should work.

Even if you want to extend Spring abstract test classes at least pay attention that some of them are deprecated. For example class AbstractTransactionalDataSourceSpringContextTests is deprecated.

Cultrate answered 14/5, 2012 at 9:35 Comment(3)
Would you please provide me a example for @RunWith(SpringJUnit4ClassRunner.class) ??Mildred
if you write a example for AbstractTransactionalDataSourceSpringContextTests that would be good..Mildred
Sorry for delay. The example is very simple. Just remove "extends..." and add annotation I wrote to class. Then try to run the test.Cultrate
C
6

JUnit Jupiter, aka "JUnit 5": use @BeforeAll

If you use the newer JUnit Jupiter (Java 8 onward), you'll want to replace @Before with @BeforeAll.

Furthermore, you'll need to either annotate your test class with @TestInstance(Lifecycle.PER_CLASS) or make the @BeforeAll method static. Here's an example:

@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();
    }
}

Understanding Lifecycle.PER_CLASS

The likely reason JUnit 5 is more stringent with this -- demanding either static or Lifecycle.PER_CLASS -- is that it wants the test author to acknowledge that any resource instance initialized in a @BeforeAll method will genuinely be shared across each individual unit test method within the class. This could compromise their isolation, for example if the sharedResource in the above example isn't stateless/idempotent.

If sharedResource cannot be safely shared (or if it's reasonably leightweight), the init method should be annotated with @BeforeEach instead, which would create a new instance before executing each individual test within the class.

The Javadoc for TestInstance explain how using Lifecycle.PER_CLASS actually enforces a single instance of the test class; whereas the behaviour of JUnit 4 and earlier was equivalent to Lifecycle.PER_METHOD, which created a new instance of the test class for each @Test method contained therein. This would somewhat mislead the author to suppose that @Before was only executed once for each of those tests.

Cuneiform answered 27/1, 2022 at 11:50 Comment(0)
Q
3

If you use auto import in an IDE, make sure the @Test and @Before are imported from the org.junit package.

Quaternity answered 8/3, 2021 at 12:0 Comment(0)
C
0

in my case, I had that problem the solution was to change the java access modifier, It was way private.

before (not working) @Test void validate() throws Exception {}

after (working) @Test public void validate() throws Exception {}

Crider answered 30/10, 2020 at 21:40 Comment(0)
D
0
  • In my case I just moved stuff from @Before / @BeforeEach annotated setUp() method to the constructor of my unit-test class.
  • As per this thread using constructor is 'equivalent' to @Before method

I can't explain why it fixed the problem but I was facing this in one particular class and it did indeed do the trick.

Disputatious answered 25/5, 2023 at 14:22 Comment(0)
O
0

In my case,

  1. I had multiple @Before in my test classes. I consolidate them into one and the problem's gone.
  2. Please make sure your test class doesn't extend TestCase().
  3. All of your test-related assertions should come from org.junit
import org.junit.Assert.assertEquals
import org.junit.Before
import org.junit.Test
...

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

    initDatabase()
    loadDefinition()
}
Obturate answered 14/6 at 18:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.