Reputation: 122392
I have some common set up code that I've factored out to a method marked with @Before
. However, it is not necessary for all this code to run for every single test. Is there a way to mark it so the @Before
method only runs before certain tests?
Upvotes: 88
Views: 103076
Reputation: 1
Alternative to @Nested on JUnit4 :
@RunWith(Suite.class)
@SuiteClasses({Testing.TestWithoutBefore.class, Testing .TestWithBefore.class})
public class Testing {
static class TestWithoutBefore{
@Test
public void testmethod1() {
System.out.println("This is method 1");
}
@Test
public void testmethod2() {
System.out.println("This is method 2");
}
@Test
public void testmethod3() {
System.out.println("This is method 3");
}
}
static class TestWithBefore{
@Before
public void init() {
System.out.println("Init");
}
@Test
public void testmethod1() {
System.out.println("This is method 1");
}
@Test
public void testmethod2() {
System.out.println("This is method 2");
}
@Test
public void testmethod3() {
System.out.println("This is method 3");
}
}
}
Upvotes: 0
Reputation: 308733
Now that it's 2023, I'd recommend sticking with JUnit 5.x
I'd also say that this is probably a micro-optimization. I would not go to the effort until I measured my test time and saw that running the code when it wasn't necessary added a significant amount of time.
Upvotes: 3
Reputation: 18192
Totally agree with the point of moving the related code to an inner class. So here what I have done.
@Nested
@BeforeEach
Here is the code:
class Testing {
@Test
public void testextmethod1() {
System.out.println("test ext method 1");
}
@Nested
class TestNest{
@BeforeEach
public void init() {
System.out.println("Init");
}
@Test
public void testmethod1() {
System.out.println("This is method 1");
}
@Test
public void testmethod2() {
System.out.println("This is method 2");
}
@Test
public void testmethod3() {
System.out.println("This is method 3");
}
}
@Test
public void testextmethod2() {
System.out.println("test ext method 2");
}
}
Here is the output
test ext method 1
test ext method 2
Init
This is method 1
Init
This is method 2
Init
This is method 3
Note: I am not sure if this is supported in Junit4. I am doing this in JUnit5
Upvotes: 54
Reputation: 196
JUnit 4.12 provide Enclosed Runner like
@RunWith(Enclosed.class)
public class GlobalTest{
@RunWith(MockitoJUnitRunner.class)
public class InnerTest{
}
}
Upvotes: 0
Reputation: 236
Not sure about @Before, but I recently came up with a strategy for @After block to run selectively. The implementation was straight forward. I have some flags set to default values as part of the test class. They are reset to default values in @Before class. In the class I need to do things specific to a flag, I set those flags & in @After I check for flag values to do the respective jobs.
Upvotes: 1
Reputation: 9309
It is possible to achieve also via Assume from JUnit. And then you can check the method name for which you want to process @Before
.
public class MyTest {
@Rule
public TestName testName = new TestName();
@Before
public void setUp() {
assumeTrue(testName.getMethodName().equals("myMethodName"));
// setup follows
}
}
Check the topic for more insights about @Rule
.
Upvotes: 9
Reputation: 14868
Just move out the tests that don't need the setup code into a separate test class. If you have some other code common to the tests that would be helpful to keep, move that out into a helper class.
Upvotes: 60