Junit #Runwith - with different Runners ; how does it work - junit

I am trying to understand how #RunWith can accept different types of Runners. How does Junit understand or accept a different Runner and flex to run with a different runners (like SpringRunner , MockitoRunner), which are written by different vendors altogether.

The class must extend the abstract class Runner.
From the javadoc
Element Detail
value
public abstract Class<? extends Runner> value
Returns:
a Runner class (must have a constructor that takes a single Class to run)
Any vendor can write a class which extends Runner and Junit 4 can use it. Junit 4 depends only on the abstract class.

Related

Static with state and JUNIT tests

We are using Junit to run our tests and inside of our business code we have an instance method of a service that access a static class that has state. If Junit runs sequentially for each method of a class by default, I mean with one single thread, if for each test method I set the needed static state, it would not be a problem, right?
In order to initialize this state of the static class, I am using static blocks instead of beforeClass because sometimes all test methods of a class have the same state for that static class. Is this ok or should I use #BeforeClass?
Thanks

Junit test case with Mockito

I am creating junit test cases for my project. I have the below code, where I would like to create a mock,
String propertyFilePath = System.getProperty("path.to.properties");
Resource propertyFile = new FileSystemResourceLoader().getResource(propertyFilePath);
Properties properties = PropertiesLoaderUtils.loadProperties(propertyFile);
I am using junit and mockito-core jar. I tried with below code,
System.setProperty("path.to.properties", "dummyPathToProperties"); //invalid Path
Properties properties = mock(Properties.class);
Resource propertyFile = new FileSystemResourceLoader().getResource("dummyPathToProperties");
when(PropertiesLoaderUtils.loadProperties(propertyFile)).thenReturn(properties);
With above code it throws error when mocking loadProperties method. How can I mock a spring static class and return my mock properties object ?
Any help will be really appreciated.
Mocking static methods requires you to go down the full nine yards and make use of PowerMock. The exact steps to mock static methods are outlined in their documentation for example.
In essence:
Use the #RunWith(PowerMockRunner.class) annotation at the class-level of the test case.
Use the #PrepareForTest(ClassThatContainsStaticMethod.class) annotation at the class-level of the test case.
Use PowerMock.mockStatic(ClassThatContainsStaticMethod.class) to mock all methods of this class.
Use PowerMock.replay(ClassThatContainsStaticMethod.class) to change the class to replay mode.
Use PowerMock.verify(ClassThatContainsStaticMethod.class) to change the class to verify mode.
But of course: consider not using PowerMock; by changing your code so that you don't have to mock the static call. But of course, it is kinda weird to add a wrapper around such a framework-provided static method.

What is the scope of the #SuppressStaticInitializationFor PowerMock annotation?

Does anyone know what is the scope of this annotation? For example, if I have multiple JUnit test classes that run sequentially in the same VM, and the first test uses #SuppressStaticInitializationFor, does that suppress the static initialization for all the subsequent test classes, too? I ask because I am under the impression that static state persists for the life of the JVM.
The scope is per classloader. Once you've used #SuppressStaticInitializationFor it'll affect the class in all other tests. You can however #SuppressStaticInitializationFor at the method level instead and that way it won't affect other tests.
you can use #SuppressStaticInitializationFor annotation at the class-level or at the method-level of the test where you want it to be suppressed.
#RunWith(PowerMockRunner.class)
#SuppressStaticInitializationFor("com.main.java.CassName")
public class TestClassName extends PowerMockTestCase {
//code
#SuppressStaticInitializationFor("com.main.java.AnotherClassName")
public void testMethod() {
//code
}
}
This way you can control which method should suppress static initializers(constructors) and for which class.

Why Junit still allow a class extend TestCase to use the annotation #Test in it?

I know in Junit, the class extend TestCase cannot support #Before and #After. But it still allow to use #Test?
I know without #Test, if we want to run this class, we could override the runTest method and define the method to be invoked. This is not convenient. Because if we mark the #Test in method of this class., it could run directly. Can anyone tell me the mechanism about how to invoke the method with #Test about this class?
By the way, If I want put a lot of tests into a TestSuite, Should I choose a class extend TestCase or define a arbitrary class with #Test as the Single Test Class ?
The TestCase class is from Junit 3 and should not be used in Junit 4 + classes.
If you extend TestCase, and use the Junit 3 Test runners then your test method names need to start with the word "test". (Junit 3 test runners use Java reflection to find and invoke all methods that start with the word "test")
Relying on TestClass hindered test class designs because you were forced to extend that class which made somethings hard to test. There also wasn't anything equivalent to Junit4's #BeforeClass or #AfterClass which meant you had to do all the more complicated multi-test fixture set up and tear down yourself.
To run many Junit4 test classes at once as a Test Suite, you can create a new empty class with the #RunWith and #SuiteClasses annotations as shown below:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses(
{
TestClassA.class,
TestClassB.class
}
)
public class MyTestSuite{
}

Eclipse JUnit #Before annotation problem

I'm experiencing some difficulties using JUnit 4.5 in Eclipse, when I use #Before annotation it just does nothing (I may use setUp() which works of course, but I'm just wondering what is wrong), while it works perfectly in Netbeans.. Any thoughts?
Because I cam here via a Google Search, and had to dig quite a bit deeper to see the actual solution:
As #Pace said in the comments, if you extend TestCase, Eclipse treats the Test as JUnit Version 3 or older, and does not respect the #Before annotation - also descripred here: JUnit + Maven + Eclipse: Why #BeforeClass does not work?
Hence, removing the extend TestCase causes fixes the problem
If you are using JUnit 4, you can just annotate the test class or the test method with #Test annotation, instead of extending TestCase.
Since you are using JUnit 4+ there are two ways to write a test case
1 > You make your test class extend TestCase. In this case classes corresponding to Junit 3 are picked up which are not aware of #Before annotation. In this case you will have to override
/**
* Sets up the fixture, for example, open a network connection.
* This method is called before a test is executed.
*/
protected void setUp() throws Exception {
}
2 > use annotations. use #Test annotation for the method in the test class that you are interested in running as a test. There is no need for your class to extend TestCase. Also you do not have to override any method. Simply define your own method that has the logic to be executed before the test method runs and annotate it with #Before annotation.