how to mock a void method in powermock - java

How to mock a void method which is non-static, non-finalThe signature of method is as below. I'm using Powermockito.
public class Name{
public void methodName{
...
...
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest({Name.class})
public class TestClass{
#Test
public void testMethodName(){
PowerMockito.doNothing().when(Name.class, methodName);
//some when calls after this and assert later on
}
I want to DO Nothing when methodName is called. the above code is not working. it says methodName cannot be resolved.

if you want to mock a non-static method you need to specify the mock object:
public class Name{
public void methodName{
...
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest({Name.class})
public class TestClass{
#Test
public void testMethodName(){
Name myName = PowerMockito.mock(Name.class);
PowerMockito.doNothing().when(myName).methodName();
//some when calls after this and assert later on
}
}

You can Use PowerMock.createmock() for Mocking your Class Where method is There.
For e.g you have ClassA and methodA which is a Void Method.
Then You can Mock it in a below way:
A a = PowerMock.CreateMock(A.class);
a.methodA();
PowerMock.replay(a);
Note : in above case method a is void That's the reason EasyMock.expect is not return;

I'm not at an IDE at the moment, but I think you can do this:
final Name name = mock(Name.class);
doNothing().when(name).methodName();

Related

How to implement doNothing() for static void method?

Am trying to mock one static void method, I tried PowerMock but always getting NullPointer exception.
We are trying to mock the below call -
public Class XYZ{
public void method1(){
....
SampleClass.methodTypeStatic1().methodTypeStatic2("xyz", "mno", classVeriable);
}
And the main class is -
public class SampleClass implements SampleClassParent{
private static SampleClass var1;
public static SampleClass methodTypeStatic1(){
if (var1 == null) {
//Do something on var1
}
return var1;
}
public void methodTypeStatic2(String localVar1, String localVar2, DifferentStaticClass localVar3) {
//Do something
}}
Am trying to mock the call like this way in my test class -
#RunWith(PowerMockRunner.class)
#PrepareForTest({SampleClass.class})
public class XYZTest{
#InjectMocks
XYZ xyzTestService;
#Test
public void testMethod1(){
...
PowerMockito.mockStatic(SampleClass.class);
PowerMockito.doNothing().when(SampleClass.methodTypeStatic1());
xyzTestService.method1();
}
Also to be mentioned SampleClass.class is not a part of our code, we have imported this external class into our code base to perform some task.
If you want to mock a non-void method, you need to define the behaviour for this method on the mock. You get the doNothing for free (as this is what mocking does),
however you need to define what the method is supposed to return.
Your test could look like this:
#Test
public void testMethod1() {
SampleClass sample = new SampleClass();
PowerMockito.mockStatic(SampleClass.class);
PowerMockito.when(SampleClass.methodTypeStatic1()).thenReturn(sample);
XYZ xyzTestService = new XYZ();
xyzTestService.method1();
}
You didn't not mention any #Mock annotations, so using #InjectMocks does nothing for you besides creating the XYZ object.

How to use expectNew for constructor with generic parameter?

I need to inject a mock object into a method where a new MyClass object is instantiated.
private MyClass<?> c;
public void myMethod(final String s) {
c = new MyClass<>(s);
c.callToMock();
}
And the class I'm mocking has a constructor with a generic parameter.
public class MyClass<T> {
public MyClass(final T t) {
// do whatever
}
}
Now, in my test, I've created a mock for the class.
When new is called, it should inject that mock.
#RunWith (PowerMockRunner.class)
public class TestClass {
#SuppressWarnings ("unchecked")
public void myMethodTest() throws Exception {
MyClass<String> myMock = (MyClass<String>) EasyMock.createMock(MyClass.class);
PowerMock.expectNew(MyClass.class, "my argument")
.andReturn(myMock);
myMock.callToMock();
EasyMock.expectLastCall().once();
EasyMock.replay(myMock);
PowerMock.replayAll();
...
}
When I run the test, it doesn't catch the new call and just instantiates an actual MyClass object.
I don't know if it's not able to match the constructor or what.
Any help would be appreciated, thanks.
You need to add a #PrepareForTest(MyTestedClass.class) on your test class to prepare the tested class to mock the new.
Here is a fully working test:
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyTestedClass.class)
public class TestClass {
#Test
#SuppressWarnings("unchecked")
public void myMethodTest() throws Exception {
MyClass<String> myMock = (MyClass<String>) EasyMock.createMock(MyClass.class);
myMock.callToMock();
PowerMock.expectNew(MyClass.class, "my argument")
.andReturn(myMock);
EasyMock.replay(myMock);
PowerMock.replayAll();
MyTestedClass tested = new MyTestedClass();
tested.myMethod("my argument");
}
}

How to mock a call of an inner method from a Junit

I have MyClass and I am doing a test-class for every method (Method1Test)
public class MyClass {
public int method1(){
int a = method2();
return a;
}
public int method2(){
return 0;
}
}
#RunWith(MockitoJUnitRunner.class)
public class Method1Test {
#InjectMocks
private MyClass myClass = new MyClass();
#Before
public void setup(){}
#Test
public void test01(){
Mockito.when(myClass.method2()).thenReturn(25);
int a = myClass.method1();
assertTrue("We did it!!!",a==25);
}
}
The problem is that I am not able to mock the call to method2 to make it return a diferent value. The Mockito sentence don't do the work.
Very thanks ^_^
You have to create a spy on the class-under-test and partially mock it by redefining the behavior for the method2() of the spy
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
public class Method1Test {
private MyClass myClass = new MyClass();
#Test
public void test01(){
//given
MyClass spy = spy(myClass); //create a spy for class-under-test
when(spy.method2()).thenReturn(25); //partially override behavior of the spy
//when
int a = spy.method1(); //make the call to method1 of the _spy_!
//then
assertEquals(25, a);
}
}
Apart from this, you don't require neither the Mockito Runner nor the #InjectMocks for your test as you're doing no injection of #Mock annotated mocks into the class-under-test.
Further, the message in the assertTrue statement is only displayed, when the condition of the assertion is NOT fulfilled. So it should be at least "We failed!!!" ;)
In the end I find a transversal solution without create a new class (I haven't been able to do it because it is forbbiden in the actual project). I have overwrited the method in the test.
The solution is
public class MyClass {
public int method1(){
int a=0;
a=method2();
return a;
}
public int method2(){
return 1;
}
}
#RunWith(MockitoJUnitRunner.class)
public class Method1Test {
#InjectMocks
private MyClass myClass = new MyClass(){
public int method2(){
return 25;
}
};
#Before
public void setup(){}
#Test
public void test001(){
Mockito.when(myClass.method2()).thenReturn(25);
int a = myClass.method1();
assertTrue("We did it!!!",a==25);
}
}
I tried the solution using the code below, but It didn't pass.
Mockito.when(myClass.method2()).thenReturn(25);
Afterwards, Instead of the code snippet above, I tried something different and the test passed successfully. Take a look:
Mockito.doReturn(25).when(myClass).method2();
In order to mock a test (It might be a inner method), you have to use doReturn() method.
You can use doThrow(), doAnswer(), doNothing(), doReturn() and doCallRealMethod() in place of the corresponding call with when(), for any method. It is necessary when you
stub void methods
stub methods on spy objects (see below)
stub the same method more than once, to change the behaviour of a mock in the middle of a test.
but you may prefer to use these methods in place of the alternative
with when(), for all of your stubbing calls.
Furthermore information can be read here https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html#12
Instead of using mock(class) here we need to use Mockito.spy() to mock the same class we are testing. Then we can mock the method we want as follows.
#Test
public void method1Test() {
MyClass myClass = new MyClass();
MyClass myClass1 = Mockito.spy(myClass);
Mockito.doReturn(1).when(myClass1).method2();
Assert.assertEquals(1, myClass1.method1());
}
}

Stubbing the call of a super class method using Mockito(V 1.9.5)

I am trying to test a method whom depending on some conditions will execute its code or its super class's one.
Here is the code of the class and its parent:
public class ParentClass {
public Object doStuff(Parameters parameters) {
// do some business stuff
return parentResult;
}
}
The inherited class's one:
public class InheritedClass extends ParentClass {
#Override
public Object doStuff(Parameters parameters) {
if (parameters.getCondition()) {
return super.doStuff(parameters);
}
//do some business stuff
return inheritedResult;
}
}
So, when trying to test the case when the parameters.getCondition() is true, I have to mock the call on the super method and verify it.
But when I do this (mocking the call for the super.doStuff()), I also mock the call to the InhertitedClass.doStuff().
Here's the solution I tried:
#RunWith(MockitoJUnitRunner.class)
public class InheritedClassTest {
#Mock
private Parameters parameters;
#Spy
private InheritedClass inherited = new InheritedClass();
#Test
public void testDoStuff(Object parameters) throws Exception {
given(parameters.getCondition()).willReturn(true);
doCallRealMethod().doReturn(value).when(inherited).doStuff(parameters);
Mockito.verify(inherited, times(2)).doStuff(parameters);
}
}
I also tried this stubbing:
when(inherited.doStuff(parameters)).thenCallRealMethod().thenReturn(value);
and this one:
given(((ParentClass)inherited).doStuff(parameters)).willReturn(value);
In all this cases, the code of the parent class was really executed.
So, I was wondering if there is any efficient way to mock the call of the super class method using mockito?
You can use Mockito's spy(), which you already tried to do. But I think a different way of using spy() will make it work.
ParentClass.java
public class ParentClass {
public String doStuff(final String parameters) {
return "parent";
}
}
InheritedClass.java
public class InheritedClass extends ParentClass {
#Override
public String doStuff(final String parameters) {
if (parameters.equals("do parent")) {
return super.doStuff(parameters);
}
return "child";
}
}
InheritedClassTest.java
public class InheritedClassTest {
#Test
public void testDoStuff() throws Exception {
final InheritedClass inheritedClass = Mockito.spy(new InheritedClass());
Mockito.doReturn("mocked parent").when((ParentClass)inheritedClass).doStuff(Mockito.eq("do parent"));
final String result = inheritedClass.doStuff("do parent");
assertEquals("mocked parent", result);
assertNotEquals("parent", result);
final String resultChild = inheritedClass.doStuff("aaa");
assertEquals("child", resultChild);
}
}
However, I do not think using spy() is a good practice. I would personally refactor your code.

Mock inherited protected method

I here have a simplified version of my problem. Class A has a protected method. Class B inherits this method.
public class A{
protected String getString(){
//some Code
}
}
public class B extends A{
public void doSomething(){
//someCode
String result = getString();
}
}
I now write a Unit-Test with Mockito, which is in another package-test and I want to test the doSomething() method. To do that, I need to mock the getString()-call. Since the method is protected and my test-class is in a differnet package, I can't use doReturn(...).when(classUnderTest).getString(). The thing is, that I spy on class B. So I can't use mock(new B(), Mockito.CALLS_REAL_METHODS).
I tried getting the protected method via Reflection:
Method getString = classUnderTest.getClass().getDeclaredMethod("getString");
getString.setAccessible(true);
But I then don't know how to use this inside doReturn().
You can use 'override and subclass'
B b = new B() {
#Override
protected String getString() {
return "FAKE VALUE FOR TESTING PURPOSES";
};
};
There might be a cleaner way of doing this, but here goes...
Create a mock for "A"
Create another class that extends B and overrides the method
Make the overridden method call the mock
For example...
private A partialMock;
private B classUnderTest;
#Before
public void setup() {
partialMock = mock(A.class);
classUnderTest = new B() {
#Override
protected String getString() {
return partialMock.getString();
}
};
}
#Test
public void shouldDoSomething() {
when(partialMock.toString()).thenReturn("[THE MOCKED RESPONSE]");
classUnderTest.doSomething();
// ...verify stuff...
}
Obviously you don't even need to use mocking, you can just return something directly from the overridden method.
Something like following worked for me, using doReturn() and Junit5's ReflectionSupport.
[Note: I tested on Mockito 3.12.4]
var a = spy(new A);
ReflectionSupport.invokeMethod(
a.getClass().getSuperclass().getDeclaredMethod("getString"),
doReturn("FAKE VALUE FOR TESTING PURPOSES").when(a));

Categories

Resources