Unable to stub a static method call using PowerMockito - java

I have a file Util.java:
public class Util {
public static int returnInt() {
return 1;
}
public static String returnString() {
return "string";
}
}
Another class:
public class ClassToTest {
public String methodToTest() {
return Util.returnString();
}
}
I want to test it using TestNg and PowerMockito:
#RunWith(PowerMockRunner.class)
#PrepareForTest(Util.class)
public class PharmacyConstantsTest {
ClassToTest classToTestSpy;
#BeforeMethod
public void beforeMethod() {
classToTestSpy = spy(new ClassToTest());
}
#Test
public void method() throws Exception {
mockStatic(Util.class);
when(Util.returnString()).thenReturn("xyz");
classToTestSpy.methodToTest();
}
}
However, it throws the following error:
FAILED: method
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
I tried this solution using various solutions from the web, but could not locate the mistake in my code. I need to stub the call for static method, since I need it for a legacy code.
How do I mock a static method using PowerMockito?

You need to configure TestNG to use the PowerMock object factory like this:
<suite name="dgf" verbose="10" object-factory="org.powermock.modules.testng.PowerMockObjectFactory">
<test name="dgf">
<classes>
<class name="com.mycompany.Test1"/>
<class name="com.mycompany.Test2"/>
</classes>
</test>
</suite>
in your suite.xml file of the project.
Please refer this link.

Just for the record, adding making the test class a subclass of PowerMockTestCase worked for me.
#PrepareForTest(Util.class)
public class PharmacyConstantsTest extends PowerMockTestCase {
ClassToTest classToTestSpy;
#BeforeMethod
public void beforeMethod() {
classToTestSpy = spy(new ClassToTest());
}
#Test
public void method() throws Exception {
mockStatic(Util.class);
when(Util.returnString()).thenReturn("xyz");
classToTestSpy.methodToTest();
}
}

Use PowerMockito methods instead of the Mockito's. The docs states that:
PowerMockito extends Mockito functionality with several new features such as mocking static and private methods and more. Use PowerMock instead of Mockito where applicable.
Per instance:
PowerMockito.when(Util.returnString()).thenReturn("xyz");

Related

Run method before each test

Im using testng 6.11 and writing tests in the following test class:
public class MyTest{
public int i;
public void init(){
//initialize i
}
#Test
public void test1(){
//test some
}
#Test
public void test2(){
//Here I need fresh value of i as it would be
//right after invocation of init()
//...
//test something else
}
}
Is it possible to make testng run init() method before invocation of each test in a test class?
Annotate init() with #BeforeMethod annotation. See http://testng.org/doc/documentation-main.html#annotations
Sure, your can use the annotation for that
#BeforeTest: The annotated method will be run before any test method belonging to the classes inside the tag is run.
You can use #BeforeMethod annotatation to execute any method before every test.
Example

Mocking static method of the interface in Java

I got an interface with a static method in it. And I want to mock this method for unit tests.
Here's an example of such an interface:
public interface IClass {
static String create(String s) {
System.out.println("Method create is called");
return s;
}
}
I was trying to mock this method using PowerMockito:
#RunWith(PowerMockRunner.class)
#PrepareForTest(IClass.class)
public class IClassTest {
#Before
public void setUp() {
PowerMockito.mockStatic(IClass.class);
ClassImpl cl = mock(ClassImpl.class);
Mockito.when(IClass.create(any())).thenReturn(cl);
}
#Test
public void mockInterfaceClassTest() {
System.out.println(IClass.create("Test"));
}
}
Unfortunately, the mocking is not being done and even more, as soon as in my setUp() method I'm trying to setup mock: Mockito.when(IClass.create(any())).thenReturn(cl); actually, the method is being called (I got message in console "Method create is called"), which is undesired for sure.
Is there any possibility to mock static method inside interface?

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() {
}
}

How to instantiate a shared resource in JUnit

I noticed that jUnit runs the constructor of my test class for each method being tested. Here's an example:
public class TestTest {
protected BigUglyResource bur;
public TestTest(){
bur=new BigUglyResource();
System.out.println("TestTest()");
}
#Test
public void test1(){
System.out.printf("test1()\n");
}
#Test
public void test2(){
System.out.printf("test2()\n");
}
#Test
public void test3(){
System.out.printf("test3()\n");
}
}
Gives the following result:
TestTest()
test1()
TestTest()
test2()
TestTest()
test3()
Calling the constructor to BigUglyResource is too time-consuming, I'd prefer to build it only once. I know you can use #BeforeClass to run a method once, but #BeforeClass is only for static methods. Static methods can't access a class property like BigUglyResource in the example above. Other than building a Singleton, what options are there?
Can't you declare the BigUglyResource static? This is how I normally do it.
private static BigUglyResource bur;
#BeforeClass
public static void before(){
bur=new BigUglyResource();
}
You could make "bur" static:
protected static BigUglyResource bur;
And use #BeforeClass.
For JUnit5 users: you have to use #BeforeAll annotation instead of #BeforeEach, the rest stays the same as in bruno's and Russ'es answers.
private static BigUglyResource bur;
#BeforeAll
public static void before(){
bur=new BigUglyResource();
}

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