Mocking static methods with Powermockito - unit-testing

I am trying to mock static method with PowerMockito. I have referred to various stackoverflow answers such as this:Mocking static methods with PowerMock and Mockito
But I am getting : org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced argument matcher detected here exception.
I have spent hours debugging my code and google searching but to no avail. What am I missing here?
* Note: I am running it as a testng test. *
I have added comments in my code that may help you understand what I am trying to do.
The full stack trace is:
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced argument matcher detected here:
at MyClassTest.testMethod1(MyClassTest.java:24)`
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo")) `
Also, this error might show up because you use argument matchers with methods that cannot be mocked.
Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
Mocking methods declared on non-public parent classes is not supported.`
at MyClassTest.testMethod1(MyClassTest.java:24)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
at org.testng.TestRunner.privateRun(TestRunner.java:767)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
at org.testng.SuiteRunner.run(SuiteRunner.java:254)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1224)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1149)
at org.testng.TestNG.run(TestNG.java:1057)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:132)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:230)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:76)
`
Below is my code:
Test Class
import static org.mockito.Matchers.anyString;
import org.junit.runner.RunWith;
import org.mockito.BDDMockito;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.testng.annotations.Test;
#Test
#RunWith(PowerMockRunner.class)
#PrepareForTest(AnotherClass.class)
public class MyClassTest {
MyClass myClass;
#Test
public void testMethod1() {
/*
* Mock static methods
*/
PowerMockito.mockStatic(AnotherClass.class);
BDDMockito.given(AnotherClass.yetAnotherMethod(anyString())).willReturn(Mockito.mock(String.class));
// call the method of system under test
myClass.method1();
// verify
PowerMockito.verifyStatic();
}
}
System Under Test:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
public class MyClass {
public String method1() {
String result = AnotherClass.yetAnotherMethod("Pramithas");
return result;
}
}
AnotherClass.java:
import org.springframework.stereotype.Service;
public class AnotherClass {
public static String yetAnotherMethod(String s) {
return s;
}
}

You haven't created new object for MyClass
Do not try to mock primitive types or final classes
Removed #Test annotation
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.mockito.Matchers.anyString;
import org.mockito.BDDMockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(AnotherClass.class)
public class MyClassTest {`
MyClass myClass = new MyClass();
#Test
public void testMethod1() {
/*
* Mock static methods
*/
PowerMockito.mockStatic(AnotherClass.class);
BDDMockito.given(AnotherClass.yetAnotherMethod(anyString())).willReturn("any String");
// call the method of system under test
myClass.method1();
// verify
PowerMockito.verifyStatic();
}
}
This is verified. It should work.

I got your example working with some changes:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ AnotherClass.class })
public class MyClassTest {
#Before
public void setUp() {
myClass = new MyClass();
}
#Test
public void testMethod1() {
/*
* Mock static methods
*/
PowerMockito.mockStatic(AnotherClass.class);
BDDMockito.given(AnotherClass.yetAnotherMethod(Mockito.anyString())).willReturn("Hello");
// call the method of system under test
String a = myClass.method1();
// verify
PowerMockito.verifyStatic();
}
I added AnotherClass to PrepareForTest too and I force AnotherClass mock to return a String value because Mockito can't mock final classes and I can check that myClass behave as expected. Here is my Mockito and Powermock dependencies:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.7.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.7.0RC2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>1.7.0RC2</version>
<scope>test</scope>
</dependency>

Related

powermockito spy private void method invocation

For a test class with a private void method, what is the right way to mock the behaviour of the method. The solution below invokes the method instead.
public class TestWizard {
private void testOne(){
throw new NullPointerException();
}
private void testTwo(){
testOne();
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest({TestWizard.class})
public class WTest {
#Test
public void testWizard() throws Exception {
TestWizard wizard2 = Whitebox.newInstance(TestWizard.class);
TestWizard wizard = Mockito.spy(wizard2);
PowerMockito.doNothing().when(wizard, "testTwo");
}
}
The error is:
java.lang.NullPointerException
at tuk.pos.wizard.model.TestWizard.testOne(TestWizard.java:6)
at tuk.pos.wizard.model.TestWizard.testTwo(TestWizard.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1862)
at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:824)
at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:689)
at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:401)
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:105)
Use PowerMockito.spy(...) instead of Mockito.spy(...).
Tested with PowerMockito 2.0.5
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
#RunWith(PowerMockRunner.class)
#PrepareForTest(WTest.TestWizard.class)
public class WTest {
public class TestWizard {
private void testOne(){
throw new NullPointerException();
}
private void testTwo(){
testOne();
}
}
#Test
public void testWizard() throws Exception {
TestWizard spy = PowerMockito.spy(Whitebox.newInstance(TestWizard.class));
PowerMockito.doNothing().when(spy, "testTwo");
spy.testTwo();
}
}
Try to restrict the usage of spies to legacy code. In most other cases a refactoring should be the preferred solution.

How to mock another static method in the same class which is being tested?

I am writing JUnit Test case with Mockito for a class which has two methods methodA,methodB. I would like to mock the call to the methodA from methodB in my test case.Some one help me.pls
Here is the class:
public Class Test{
public static List<Object> methodA() {
...
return list;
}
public static List<Object> methodB() {
...
list = methodA();
return list;
}
}
You will need to use PowerMockito to mock the static method.
Example:
package unitest;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(unitest.Test.class)
public class TestTest {
#Test
public void testMethodB() {
PowerMockito.mockStatic(unitest.Test.class);
PowerMockito.when(unitest.Test.methodA()).thenReturn(new ArrayList());
List b = unitest.Test.methodB();
org.junit.Assert.assertNotNull(b);
}
}

JSF-Testing with embedded TomEE: Manipulate injected object

I have a JSF-Project with one class called Label and one xhtml-page, called label.xhtml. In label.xhtml the method Label.getValue() is called via injection. The test LabelTest runs a embedded container and in a test method label.xhtml is requested and the body content will be checked. So far everything is fine, but I would like to change the value of the attribute Label.value in my test so the test can assert his own set value and not the value of the Postconstruct-method of class Label.
I put a breakpoint in the constructor of class Label. So I can see the stacktrace and I read the code of many of these methods. Maybe it is possible to change the produces class, so I can put there my own AbstractProducer in some way?
Stacktrace Label constructor
Code on GitHub or scroll down.
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
#Named
#RequestScoped
public class Label {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
#PostConstruct
public void fillValue() {
setValue("HELLO");
}
}
import org.apache.tomee.embedded.EmbeddedTomEEContainer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import javax.ejb.embeddable.EJBContainer;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.assertEquals;
public class LabelTest {
private WebDriver driver;
#Before
public void setup() {
driver = new HtmlUnitDriver();
Map<Object, Object> properties = new HashMap();
properties.put(EJBContainer.PROVIDER, EmbeddedTomEEContainer.class);
properties.put(EJBContainer.MODULES, new File[]{new File("src/main/webapp/")});
properties.put(EJBContainer.APP_NAME, "hfe");
System.setProperty("tomee.webapp.externalRepositories", "build/classes/main,build/classes/test");
EmbeddedTomEEContainer.createEJBContainer(properties);
}
#After
public void cleanup() {
driver.close();
}
#Test
public void requestHtmlPage_ThenBodyContainsPostConstructValue() {
assertEquals("HELLO", getBodyValue());
}
#Test
public void manipulateInjectedObjectAndRequestHtmlPage_ThenBodyContainsValueOfManipulatedInjectedObject() {
// how is it possible to manipulate the injected object with value=MY_VALUE?
assertEquals("MY_VALUE", getBodyValue());
}
private String getBodyValue() {
driver.get("http://localhost:8080/hfe/faces/label.xhtml");
WebElement body = driver.findElement(By.tagName("body"));
return body.getText();
}
}
label.xhtml
<html>
<h:body>
#{label.value}
</h:body>
</html>
I got a solution from the TomEE User MailingList: Using the Annotation #Specializes or using a ServletFilter. You can find the example code at the GitHub project.

Getting null response while creating Mock Dao using Mockito

I am trying to create a mock data for Dao class. Test case is running successfully but it is returning null data. I searched and implemented #Mock, #InjectMocks, Inititated MockitoAnnotation but still it is not working. The project is in spring. Context path is also correct. I have not used any other methods. First for running I am trying to just call a method and print. Please help me to solve this error.
RegionManager Class:
#Service("regionManager")
public class RegionManager implements RegionManagerIntf {
#Autowired
RegionDaoIntf regionInquiry;
private RegionDao regionDao;
#Override
public ListPojo retrieveData(String Id, String details, String code) {
return regionInquiry.retrievePData(Id, details, code);
}
public RegionDao getRegionDao() {
return regionDao;
}
public void setRegionDao(RegionDao regionDao) {
this.regionDao = regionDao;
}
}
Dao Class:
#Component
public class RegionProcessorFactory implements RegionProcessorIntf {
private static final Logger logger = Logger
.getLogger(RegionProcessorFactory.class);
#Override
public ListPojo retrieveData(String Id,
String details, String code) {
ListPojo listPojo = new ListPojo();
//Do some action
return listPojo;
}
}
ListPojo:
It contains getter setters.
Test Class:
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.test.context.ContextConfiguration;
import com.fasterxml.jackson.databind.ObjectMapper;
#RunWith(MockitoJUnitRunner.class)
#ContextConfiguration({"classpath*:spring/beanRefContext.xml"})
public class RegionManagerTest
{
private String Id = "12345";
private String Code = "123";
private String details = "12";
ObjectMapper mapper;
#Mock
private RegionProcessorFactory dao;
#Mock
private ListPojo listPojo;
#InjectMocks
private RegionManager service;
/**
* Before method will be called before executing every test case
*/
#Before
public void initialize() {
System.out.println("In initialize");
MockitoAnnotations.initMocks(this);
dao = mock(RegionProcessorFactory.class);
listPojo = mock(ListPojo.class);
service = new RegionManager();
service.setRegionDao(dao);
}
#Test
public void CreateDatabaseMock() throws Exception
{
System.out.println("dao result :: "+dao.retrieveData(Id, "", ""));
when(dao.retrieveData(Id, "", "")).thenReturn(listPojo);
verify(dao).retrieveData(Id, "", "");
}
/**
* After method will be called after executing every test case
*/
#After
public void TearDownClass() {
}
}
First: If you are using #RunWith(MockitoJUnitRunner.class) there is no need for MockitoAnnotations.initMocks(this); more on that here
Second: Everything with #Mock will be mocked and mockito will try to inject it into object annotated with #InjectMocks which mockito will instantiate(in old mockito versions you had to create the object yourself) so following lines are not needed:
dao = mock(RegionProcessorFactory.class);
listPojo = mock(ListPojo.class);
service = new RegionManager();
service.setRegionDao(dao);
Third: The actual execution should come after stubbing
#Test
public void CreateDatabaseMock() throws Exception{
when(dao.retrieveData(Id, "", "")).thenReturn(listPojo);
System.out.println("dao result :: "+dao.retrieveData(Id, "", ""));
verify(dao).retrieveData(Id, "", "");
}

Can an abstract class be mocked using mockito?

In a class under test, if its constructor takes in an abstract class parameter can we mock it using mockito?
Ex
public abstract AbstractClass{
}
//Class under test
public class SourceClass{
SourceClass(AbstractClass abstractClass){}
}
#RunWith(MockitoJUnitRunner.class
public SourceClassTest{
#Mock
AbstractClass abstractClass;
}
whenever I do this i get this error
java.lang.ExceptionInInitializerError
Ther version of mockito I am using i 1.8.5
Well, this code below works fine, just tell me if I need to add some comments to explain what I wrote, ok? (hey, I am using Mockito 1.10.8):
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
abstract class AbstractClassToTest {
public abstract String doSomething();
}
class ConcreteClass {
private String something;
public ConcreteClass(AbstractClassToTest aClass){
this.something = aClass.doSomething();
}
public String getSomething(){
return this.something;
}
}
#RunWith(MockitoJUnitRunner.class)
public class TempTest {
#Mock
private AbstractClassToTest myClass;
#Test
public void canAbstractClassToTestBeMocked() {
String expectedResult = "hello world!";
Mockito
.when(myClass.doSomething())
.thenReturn(expectedResult);
String actualResult = myClass.doSomething();
Assert.assertEquals(expectedResult, actualResult);
}
#Test
public void canConcreteClassBeInstantiatedWithMock() {
String expectedResult = "hello world!";
Mockito
.when(myClass.doSomething())
.thenReturn(expectedResult);
ConcreteClass concrete = new ConcreteClass(myClass);
String actualResult = concrete.getSomething();
Assert.assertEquals(expectedResult, actualResult);
}
}
You cannot mock abstract classes, you have to mock a concrete one and pass that along. Just as regular code can't instantiate abstract classes.