Can I exclude an individual test from #BeforeEach in JUnit5? - java

Is it possible to exclude an individual test from #BeforeEach in JUnit5?
Kindly guide me for this.
Thank you

You could use TestInfo and write this condition by inspecting the test name:
#BeforeEach
void init(TestInfo info) {
if (info.getDisplayName().equals("mySpecialTestName") {
return; // skip #BeforeEach in mySpecialTestName test
}
}
but it would be cleaner to move the tests that don't need #BeforeEach to a separate class.

You can move the tests that require the before-each behaviour into an inner ˋ#Nested´ subclass and put the before-each method there.
public class MyClassTest {
#Test
void test1(){}
#Nested
private class NestedTestBlock {
#BeforeEach
void beforeEach(){}
#Test
void test2() {}
#Test
void test3() {}
}
}

Related

How to do a BeforeEach on all of my integration test files

I have a bit of code I'd like to run in every #BeforeEach of all my integration tests files. Basically the code I need to add is the following :
#MockBean
RequestInterceptor interceptor; // I NEED THIS
#BeforeEach
public void initTest() throws Exception {
Mockito.when(interceptor.preHandle(any(), any(), any())).thenReturn(true); // AND THIS
}
Is there a way to avoid duplicating this part in every files ? Maybe I can create a test configuration file and use an annotation in my test files. As I am very new to java spring boot I would appreciate some help. Thanks.
You can create super class e.g. BaseTest and move this code there. And then every your test should just extend BaseTest. Even more you can set all Annotation in this class. E.g.:
#AutoConfigureMockMvc
#MockitoSettings(strictness = Strictness.STRICT_STUBS)
#ExtendWith(MockitoExtension.class)
#ExtendWith(SpringExtension.class)
#ActiveProfiles("test")
#SpringBootTest
public class BaseTest {
#MockBean
RequestInterceptor interceptor; // I NEED THIS
#BeforeEach
public void initTest() throws Exception {
Mockito.when(interceptor.preHandle(any(), any(), any())).thenReturn(true); // AND THIS
}
}
And then all your tests:
class MeasurementsServiceTest extends BaseTest {
//test methods here
}
Well you can make a parent base class that would have the BeforeEach method and then just inherit that class on all of the other ones
public class BaseTestClass {
#BeforeEach
public void setUp(){
System.out.println("Base Test Class");
}
}
public class InheritsFromBase extends BaseTestClass {
// here goes test code
}

How to execute a piece of code once before all test classes start?

How can I execute a method once before all tests in all classes start?
I have a program that needs a system property to be set before any test start. Is there any way to do that?
Note: #BeforeClass or #Before are used just for the same test class. In my case, I'm looking for a way to execute a method before all test classes start.
To setup precondition to your test cases you can use something like this -
#Before
public void setUp(){
// Set up you preconditions here
// This piece of code will be executed before any of the test case execute
}
if you need to run that method before the start of all test you should use the annotation #BeforeClass or if you need to execute the same method every time you will execute a test method of that class you must use #Before
f.e
#Before
public void executedBeforeEach() {
//this method will execute before every single test
}
#Test
public void EmptyCollection() {
assertTrue(testList.isEmpty());
}
You can make use of a Test Suite.
The test suite
#RunWith(Suite.class)
#Suite.SuiteClasses({ TestClass.class, Test2Class.class, })
public class TestSuite {
#BeforeClass
public static void setup() {
// the setup
}
}
and, the test classes
public class Test2Class {
#Test
public void test2() {
// some test
}
}
public class TestClass {
#Test
public void test() {
// some test
}
}
Or, you can have a base class which handles the setup
public class TestBase {
#BeforeClass
public static void setup() {
// setup
}
}
and, then the test classes can extend the base class
public class TestClass extends TestBase {
#Test
public void test() {
// some test
}
}
public class Test2Class extends TestBase {
#Test
public void test() {
// some test
}
}
However, this will call the setup method in TestBase for all its subclasses everytime each of them executes.

#Before/#BeforeEach inheritance behaviour change JUnit4 / JUnit5

When migrating from JUnit4 to JUnit5 I found a change in the behaviour of JUnit4 and JUnit5 and wanted to check if the change was a bug in JUnit4 or in JUnit5 and how to do it correctly.
Lets assume the following structure:
One base class
public class BaseTestClass {
#Before
public void setUp(){
System.out.println("Base Test Class");
}
}
Another class that inherits from this base class
public class InheritsFromBase extends BaseTestClass {
#Override
public void setUp() {
System.out.println("I inherit from base");
super.setUp();
}
}
And an actual test class
public class ActualTests extends InheritsFromBase {
#Test
public void myTest(){
Assert.assertTrue(true);
}
}
If I run myTest() in JUnit 4 then the setUp() method of both, BaseTestClass and InheritsFromBase is called.
After migrating this code to JUnit5, the setUp() methods are not called anymore. I had to manually add the #BeforeEach annotation on InheritsFromBase.
Resulting in the following classes:
public class BaseTestClass {
#BeforeEach
public void setUp(){
System.out.println("Base Test Class");
}
}
public class InheritsFromBase extends BaseTestClass {
#Override
#BeforeEach
public void setUp() {
System.out.println("I inherit from base");
super.setUp();
}
}
public class ActualTests extends InheritsFromBase {
#Test
public void myTest(){
Assertions.assertTrue(true);
}
}
So my question: Was the behaviour in JUnit4 correct or in JUnit5?
The actual behavior for JUnit 5 is expected as the #BeforeEach javadoc states :
Inheritance
#BeforeEach methods are inherited from superclasses as long as they
are not overridden.
You override the setup() method that contains #BeforeEach in the InheritsFromBase class.
So it is not inherited any longer.
For JUnit 4, the #Before javadoc doesn't state any particularity and inheritance abilities.
So you should consider the actual behavior as "normal" but no documented.
To get the same behavior with JUnit 5, you should do the reverse what you do with JUni4 : remove #BeforeEach in the super class and add it only in the subclass.
public class BaseTestClass {
public void setUp() {
System.out.println("Base Test Class");
}
}
public class InheritsFromBase extends BaseTestClass {
#Override
#BeforeEach
public void setUp() {
System.out.println("I inherit from base");
super.setUp();
}
}
As I execute the tests, it produces as output :
I inherit from base
Base Test Class

Simple Junit class is not calling the #Before method [duplicate]

I have the following code:
#BeforeClass
public static void setUpOnce() throws InterruptedException {
fail("LOL");
}
And various other methods that are either #Before, #After, #Test or #AfterClass methods.
The test doesn't fail on start up as it seems it should. Can someone help me please?
I have JUnit 4.5
The method is failing in an immediate call to setUp() which is annotated as #before.
Class def is :
public class myTests extends TestCase {
do NOT extend TestCase AND use annotations at the same time!
If you need to create a test suite with annotations, use the RunWith annotation like:
#RunWith(Suite.class)
#Suite.SuiteClasses({ MyTests.class, OtherTest.class })
public class AllTests {
// empty
}
public class MyTests { // no extends here
#BeforeClass
public static void setUpOnce() throws InterruptedException {
...
#Test
...
(by convention: class names with uppercase letter)
the method must be static and not directly call fail (otherwise the other methods won't be executed).
The following class shows all the standard JUnit 4 method types:
public class Sample {
#BeforeClass
public static void beforeClass() {
System.out.println("#BeforeClass");
}
#Before
public void before() {
System.out.println("#Before");
}
#Test
public void test() {
System.out.println("#Test");
}
#After
public void after() {
System.out.println("#After");
}
#AfterClass
public static void afterClass() {
System.out.println("#AfterClass");
}
}
and the ouput is (not surprisingly):
#BeforeClass
#Before
#Test
#After
#AfterClass
Make sure you imported #Test from the correct package.
Correct package: org.junit.Test
Incorrect pacakge: org.junit.jupiter.api.Test
Please note that this is a solution for: If your #Before, #Atter, etc did not get called at all.
Make sure that :
Your test class doesn't inherits from TestCase
The #BeforeClass method is static
You don't have more than one #BeforeClass method in test class hierarchy (only the most specialized #BeforeClass method will be executed)
Check your imports.
#Before
#After
#BeforeClass (this should be static)
#AfterClass (this should be static)
and #Test annotations should import from same path.
In order that the before annotated function will run , I had to do the following:
If you use Maven , add a dependency to Junit 4.11+:
<properties>
<version.java>1.7</version.java>
<version.log4j>1.2.13</version.log4j>
<version.mockito>1.9.0</version.mockito>
<version.power-mockito>1.4.12</version.power-mockito>
<version.junit>4.11</version.junit>
<version.power-mockito>1.4.12</version.power-mockito>
</properties>
and the dependency:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${version.junit}</version>
<scope>test</scope>
</dependency>
.
.
.
</dependencies>
Make sure your Junit Test class is not extending The TestCase class, since this will cause overlapping with Older version:
public class TuxedoExceptionMapperTest{
protected TuxedoExceptionMapper subject;
#Before
public void before() throws Exception {
subject = TuxedoExceptionMapper.getInstance();
System.out.println("Start");
MockitoAnnotations.initMocks(this);
}
}

Using PowerMockRunner with Junit Test Suite

I'm trying to create a Junit test suite along with using PowerMockRunner but it does not work.
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(MainTest.class)
#Suite.SuiteClasses({ MainTest.Class1Test.class })
#PrepareForTest({
StaticFieldsProvider.class
})
public class MainTest extends Suite {
public MainTest(Class<?> klass, RunnerBuilder builder)
throws InitializationError {
super(klass, builder);
}
public static class TestBase {
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
PowerMockito.mockStatic(StaticFieldsProvider.class);
}
}
public static class Class1Test extends TestBase {
#Before
public void setUp() {
super.setUp();
}
#Test
public void test(){
assertTrue(true);
}
}
}
When I try to run, it fails with error -
java.lang.IllegalArgumentException: Test class can only have one constructor
at org.junit.runners.model.TestClass.(TestClass.java:40)
Any suggestions on how to use PowerMockRunner in above case?
Thanks
This is an old question, so we may get no resolution on whether or not this solution works for the OP; but this might work (I can't verify without having access to StaticFieldsProvider, but it works if I swap that out with one of my own classes). I would love for someone to edit and add more explanation as to why this works:
#RunWith(PowerMockRunner.class)
// * Delegate to Suite.class instead of MainTest.class *
#PowerMockRunnerDelegate(Suite.class)
#Suite.SuiteClasses({ MainTest.Class1Test.class })
#PrepareForTest({
StaticFieldsProvider.class
})
// * Don't extend Suite *
public class MainTest {
// * Remove constructor *
public static class TestBase {
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
PowerMockito.mockStatic(StaticFieldsProvider.class);
}
}
public static class Class1Test extends TestBase {
#Before
public void setUp() {
super.setUp();
}
#Test
public void test(){
assertTrue(true);
}
}
}
In case it helps someone else, I had a slightly different scenario in that only a couple of the classes in my suite need PowerMockRunner (and don't mock out the same thing, so the mock needs to happen in each individual test class instead of in the runner). It appears that as long as I #PrepareForTest in my runner (as above) the classes I will need in some of the test classes, I can still create the mocks in the #Before (or wherever) of the applicable test class. Hope this helps.
You must not extend Suite, because this is a part of JUnit 3 and you are using JUnit 4. (Remove the extends and the constructor.) See the JUnit Wiki for more datails about Suites in JUnit 4.

Categories

Resources