#RunWith(PowerMockRunner.class) vs #ExtendWith(MockitoExtension.class) - java

I try to mock a static class PowerMockito.mockStatic(Static.class);. When #RunWith(PowerMockRunner.class), the code runs successfully but when I use #ExtendWith(MockitoExtension.class), it throws org.powermock.api.mockito.ClassNotPreparedException. Is it possible to mock a static class with #ExtendWith(MockitoExtension.class)?
This is my setup
#RunWith(PowerMockRunner.class)
#PrepareForTest({SmeRestClient.class})
public class PreScreeningServiceImplTest extends PreScreeningServiceImplTestHelper {
#Before
public void setup() {
PowerMockito.mockStatic(Static.class);
}
}
#RunWith(JUnitParamsRunner.class)
#ExtendWith(MockitoExtension.class)
#PrepareForTest(SmeRestClient.class)
public class PreScreeningServiceImplTest extends PreScreeningServiceImplTestHelper {
#Before
public void setup() {
PowerMockito.mockStatic(Static.class);
}
}
Full error code
org.powermock.api.mockito.ClassNotPreparedException:
The class com.ime.restful.Static not prepared for test.
To prepare this class, add class to the '#PrepareForTest' annotation.
In case if you don't use this annotation, add the annotation on class or method level.

Related

Reading custom annotation for JUNIT

I have a custom annotation which I use as config to start off one time set-up for Junit.
#Target(TYPE) #Retention(RUNTIME)
public #interface MyAnnotation{
String host();
int port();
}
Test class:
#MyAnnotation(host="0.0.0.0", port=4567)
public class MyTest extends MyAbstractClass{
#Test
public void myTest(){
//do testy things
}
}
Superclass:
public class MyAbstractClass{
#BeforeAll
public static void start(){
Config cfg = readConfig();
//Use config to do one time set-up
}
private static Config readConfig(){
MyAnnotation ann = MyTest.class.getAnnotation(MyAnnotation.class);
return new Config(ann.host(), ann.port());
}
}
So currently, I hardcode the name of the test class (MyTest) in readConfig(..).
This won't work when I add a second test class.
One way to solve it is:
Add another #BeforeAll method in MyTest which will call the #BeforeAll in super-class and pass the class name as a param.
However, I am curious if I can read the name of the executing subclass in the superclass via some reflexion magic.
Any ideas are most welcome.
Thanks
The presence of the #BeforeAll annotation suggests you are using JUnit 5. In this case, you can use.
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.TestInfo;
public class MyAbstractClass {
#BeforeAll
public static void start(TestInfo ti) {
Config cfg=readConfig(ti.getTestClass().orElseThrow(IllegalStateException::new));
//Use config to do one time set-up
}
private static Config readConfig(Class<?> testClass) {
MyAnnotation ann = testClass.getAnnotation(MyAnnotation.class);
return new Config(ann.host(), ann.port());
}
}
See also the TestInfo API documentation.
This is not “Reflection Magic” but a feature provided by JUnit itself, but it’s also only JUnit which knows that the invocation of a static method annotated with #BeforeAll is associated with a particular test class it is going to process.

Is there any way to Mock the private method , which is there in other class

As per my knowledge, We can Mock the private method in same class by using PowerMockito.
With in the same class is working fine for me , but when i'm calling private method from the other class it's not working.
Below Example i've 2 classes , Service class and Helper classes
Helper class having private method.
#RunWith(PowerMockRunner.class)
#PrepareForTest({ Helper.class,Service.class })
#PowerMockIgnore("javax.management.*")
public class EPartnerBatchServiceTest {
private Helper helper;
#InjectMocks
private ServiceClass serviceClass;
#Before
public void setUp() throws Exception {
helper = PowerMockito.spy(new Helper());
ServiceClass = PowerMockito.spy(new serviceClass());
MockitoAnnotations.initMocks(this);
}
#Test
public void testUpdateIndividualUserStatus() throws Exception {
PowerMockito.doReturn("Test").when(helper, "privateMethod", anyString(), Matchers.anyObject());
String response = serviceClass.update(loggerId, activityLogDTO);
}
}
Sample Classes :
Class A{
value=new B().method1();
}
Class B{
public method1(){
value = method2();
}
private method2(){
return "Test";
}
}
You shouldn't be worrying with testing explicitly your private methods, since they are not accessible for the ones calling it, it's function should be tested somewhere in the flow of your public methods. But, if for some reason you need to test them explicitly, then maybe reflections and setting those methods as accessible for testing may resolve your problem.
You'll find great examples here: https://www.baeldung.com/java-method-reflection

PowerMock Mockito ignore junit FixMethodOrder

I have a little problem here, and I don't know how to solve it.
I have a class which have to make tests for some JSF beans.
In order to achieve that, I used PowerMock with Mockito for mocking the FacesContext, RequestContext and another static methods which are used inside the JSF beans.
#PrepareForTest(ClassWithStaticMethods.class)
#RunWith(PowerMockRunner.class)
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MyTestingClass extends SomeTestBaseClass{
#BeforeClass
public static void init() throws Exception{
//mocking the FacesContext and others
}
#Test
public void test0001Create(){}
#Test
public void test0002Edit(){}
#Test
public void test0003Delete(){}
}
The SomeTestBaseClass, nothing complicated.
public abstract class SomeTestBaseClass {
#BeforeClass
public static void setUpBeforeClass() throws Exception {
//...
}
#AfterClass
public static void tearDownAfterClass() throws Exception {
//...
}
}
The problem is that the order of tests is ignored (even with the FixMethodOrder annotation). If I remove PowerMockRunner (and the RunWith annotation), the order is kept but the mocking for static (and void) methods doesn't work.
But leaving the class with PowerMockRunner, the annotation #FixMethodOrder is ignored, totally.
I even tried with MockitoJUnitRunner, and here the order of tests is kept, but the mocking for static (and void) methods isn't done.
Does anyone have any idea why it is happening?
Thanks
I had the same problem getting them to run in the right order.
I solved it by using the #PowerMockRunnerDelegate annotation.
In my test class annotations:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
#RunWith(PowerMockRunner.class)
I added #PowerMockRunnerDelegate(JUnit4.class):
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
#RunWith(PowerMockRunner.class)
#PowerMockRunnerDelegate(JUnit4.class)
They now run in the expected order.
I believe this works because then it's not PowerMock that's running the tests, but JUnit 4 itself.
Like a workaround: Create a new method (let's say 'testAll'), put #Test annotation just for this (remove the #Test annotation from the rest of the methods), and then, call your testing methods inside of the annoted method.
Dirty, but it works.
#PrepareForTest(ClassWithStaticMethods.class)
#RunWith(PowerMockRunner.class)
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MyTestingClass extends SomeTestBaseClass{
#BeforeClass
public static void init() throws Exception{
//mocking the FacesContext and others
}
#Test
public void testAll(){
this.test0001Create();
this.test0002Edit();
this.test0003Delete();
}
public void test0001Create(){}
public void test0002Edit(){}
public void test0003Delete(){}
}
Please try to change sequence:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
#RunWith(PowerMockRunner.class)
#PrepareForTest(ClassWithStaticMethods.class)
I don't know why it doesn't work with the PowerMockRunner annotation but instead you could use a PowerMockRule
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MyTestingClass extends SomeTestBaseClass {
#Rule
public PowerMockRule rule = new PowerMockRule();
#BeforeClass
public static void init() throws Exception {
// mocking the FacesContext and others
}
#Test
public void test0001Create() {
}
#Test
public void test0002Create() {
}
#Test
public void test0003Create() {
}
}

#BeforeClass annotation is not working in dynamically created Test Suite

I have few JUnit Tests and I want to decide which one to use at runtime. I checked previous answers at SO and I ended up creating Test Suite dynamically.
This class is where my application starts. I have CustomTestSuite class and Main class adds Tests to my custom suite.
public class Main {
public static junit.framework.TestSuite suite()
{
CustomTestSuite suite = new CustomTestSuite();
suite.addTest(new JUnit4TestAdapter(BTest.class));
suite.addTest(new JUnit4TestAdapter(ATest.class));
return suite;
}
}
CustomTestSuite.java
public class CustomTestSuite extends TestSuite {
#BeforeClass
public static void setUp() throws Exception {
System.out.println("Before class test");
}
#After
public void tearDown() throws Exception {
System.out.println("After class test");
}
}
My ATest and BTest are simple Test classes, I will just show ATest as sample:
public class ATest{
#Test
public void testMethod() {
System.out.println("testMethod");
}
}
When I start running my project from Main class, it is expected to run the method with #BeforeClass first, do testing, and then run the method with #AfterClass annotation.
Tests are working fine but it skips setUp method and tearDown method. I tried #Before and #BeforeClass annotations both.
I am confused with suite structure. Any help would be appreciated.
Thanks
#Before and #BeforeClass are supposed to be used in Test class not in TestSuite. If need to have common setUp and tearDown for more than one Test class, then put those both methods in a super class and extend that super by ATest and BTest test classes. And also the Suite can be built and run simply with #RunWith and #SuiteClasses annotations and the CustomTestSuite class is not needed.
So the changes are as below.
The CustomTestSuite becomes TestSuper
public class TestSuper {
#BeforeClass
public static void setUp() throws Exception {
System.out.println("Before class test");
}
#After
public void tearDown() throws Exception {
System.out.println("After class test");
}
}
Now the ATest extends TestSuper
public class ATest extends TestSuper {
#Test
public void testMethod() {
System.out.println("testMethod");
}
}
Similarly BTest also should extend TestSuper.
Simply add #RunWith and #SuiteClasses annotations to Main class as below and run Main.
#RunWith(Suite.class)
#SuiteClasses({ATest.class, BTest.class})
public class Main {
}
Have a go with these changes.

Why isn't my #BeforeClass method running?

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

Categories