I am using TestNG 6.8.8, Mockito 1.9.5 and PowerMock 1.5.4. When I mock Child class and call stubbed final method, the test passes sometimes and fails sometimes with error MissingMethodInvocationException.
Is this a PowerMock bug?
public abstract class Parent implements Serializable {
protected abstract void validate();
public final Date getLastModified() {
return lastModified;
}
}
public class Child extends Parent {
#Override
protected void validate() {
// nothing for now.
}
}
import static org.powermock.api.mockito.PowerMockito.when;
#PrepareForTest({ Parent.class, Child.class })
public class ChildTest {
#Test
public final void testChildMethod() {
Child childObj = PowerMockito.mock(Child.class);
when(childObj.getLastModified()).thenReturn(new Date());
TestCodeThatResultsInCallToChild.getLastModified();
}
}
Error message:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
3. the parent of the mocked class is not public.
It is a limitation of the mock engine.
" type="org.mockito.exceptions.misusing.MissingMethodInvocationException
Related
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
I am trying to test the following class using Mockito and JUnit :
public class A {
private SomeClass someObject;
private SomeImpClass someImpObject1;
private SomeImpClass2 someImpObject2;
public A(SomeImpClass someImpObject1, SomeImpClass2 someImpObject2){
someObject = makeNewObject(someImpObject1, someImpObject2);
}
public makeNewObject(SomeImpClass1 someImpObject1, SomeImpClass2 someImpObject2){
return new SomeObject(someImpObject1,someImpObject2);
}
public usingSomeObject(){
someObject.doSomething();
}
}
So, I wrote a Unit Test using Mockito and JUnit :
#RunWith(MockitoJUnitRunner.class)
public class ATest {
#Mock
SomeImpClass1 someImpObject1;
#Mock
SomeImpClass2 someImpObject2;
#Mock
SomeObject someObject;
#Spy
A a;
#Before
public void setUp() {
when(A.makeNewObject).thenReturn(someObject);
this.A = new A(this.someImpObject1, someImpObject2);
when(someObject.doSomething).thenReturn(something);
}
}
The Issue I am facing here is, although I have stubbed the function makeNewObject to return a Mocked object of SomeClass, the code flow is still going inside the fucntion (makeNewObject) and giving a null exception.
What Am I Doing Wrong ?
I have wasted a day behind this.
Not Very Fluent with Mockito.
You wont be able to achieve what you are aiming for with spying and stubbing.
This is because your aiming at stubbing a method used in a constructor.. but you cannot start stubbing once you created a concrete object and spy it.. can't be done..
I would suggest creating a private class inside the test class which extends your class under test, override the method invoked in the constructor and then use it in your tests:
#RunWith(MockitoJUnitRunner.class)
public class ATest {
#Mock
SomeObject someObjectMock;
A a;
#Before
public void setUp() {
this.a = new MyTest();
}
private class MyTest extends ATest{
#Override
public makeNewObject(SomeImpClass1 someImpObject1, SomeImpClass2 someImpObject2){
return someObjectMock;
}
}
Now you dont need to use spying and stubbing of it also as the overriden method is always returning what you expect in the test.
I would like to perform a junit test using Mockito on the toEntity function.
#Component
public class MyEntityTransform {
public Function<MyDTO , MyEntity> toEntity = new Function<MyDTO , MyEntity >() {
#Override
public MyEntity apply(MyDTO record) {
return new MyEntity();
}
};
}
Unfortunately the toEntity is NULL when I mock the class and I don't know how I can test it correctly.
#RunWith(MockitoJUnitRunner.class)
public class MyTest {
#InjectMocks
private MyService _classUnderTest;
#Mock
private MyEntityTransform myEntityTransform
#Before
public void setUp() {
Mockito.when(this.myEntityTransform.toEntity.apply(Mockito.anyObject())).thenReturn(...);
}
}
When I RUN the JUNIT test, Mockito give me the error :
java.lang.NullPointerException
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced argument matcher detected here:
-> at com.example.MyTest.setUp(MyTest.java:38)
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.
Do you have suggestions?
You're using public fields, which is not a good idea. But anyway, what you want to mock is the function, not the instance of MyEntityTransform. So you would need something like
#InjectMocks
private MyService _classUnderTest;
#Mock // or #Spy
private MyEntityTransform myEntityTransform;
#Before
public void prepare() {
myEntityTransform.toEntity = mock(Function.class);
}
But quite frankly, I wouldn't use a public field of type Function. Instead, I would use a public method:
public class MyEntityTransform {
public MyEntity toEntity(MyDTO record) {
return new MyEntity();
}
}
Then you can mock MyEntityTransform and make its toEntity method return what you want. And if you need to pass a Function doing what the method does, use a method reference:
collection.stream().map(myEntityTranform::toEntity)
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?
I'm using Mockito and PowerMockito to instantiate a mock when a constructor is called:
#RunWith(MockitoJUnitRunner.class)
#PrepareForTest(ConVibe.class)
public class ConVibeTests {
ConVibe task;
#Mock ShapeEffect shapeEffect;
#Test
public void verify_shape_effect() {
whenNew(ShapeEffect.class).withAnyArguments().thenReturn(shapeEffect);
task.call();
// Omitted
}
// Omitted
}
This is the call to the constructor that I wanted to mock, located inside the function call() in the class conVibe:
final ShapeEffect effect = new ShapeEffect(mode, new RepService());
The fact is that the real constructor is called (where there is a DB call that obviously fail) instead of creating a mock.
What's wrong?
You're using the wrong runner - if you want to use PowerMock, you need to use the PowerMockRunner:
#RunWith(PowerMockRunner.class)
#PrepareForTest(ConVibe.class)
public class ConVibeTests {