Mockito: how to use when(instance.meth).thenAnswer without mock - java

I have try following code:
package ro.ex;
/**
* Created by roroco on 11/11/14.
*/
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import static org.mockito.Mockito.*;
public class ExTest extends junit.framework.TestCase {
class C {
public String m() {
return null;
}
}
public void testM() throws Exception {
when(new C().m()).thenAnswer(new Answer<String>() {
#Override
public String answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
return (String) args[0];
}
});
}
}
i hope i can change a real instance meth not a mock, but above code raise:
when() requires an argument which has to be 'a method call on a mock'.
my question is: how to fix it.

I assume this is a sample code you created to ask a question here but in real, C should be the class under test (not a class within your test).
Class MyClassToTest {
public String m() {...}
}
Now in your test, mock class C. #Mock C c and followed by when(c.m()).thenAnswer..... in the test method.

Not sure why you would need that, but you can use spy:
public void testM() throws Exception {
C c = Mockito.spy(new C());
// actual method
c.m();
// stubbed method
when(c.m()).thenAnswer(...);
}
Alternatively, you can mock the object, and call thenCallRealMethod() when needed.

Related

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

Non-virtual method invocation using reflection

In Java, when working with java.lang.reflect.Method how can I invoke a function without it being a virtual call?
I.e. I want this code to print "good" instead of what it currently does, which is print "bad":
Foo.java:
public class Foo {
public void doit() {
System.out.println("good");
}
}
Bar.java:
import java.lang.reflect.Method;
public class Bar extends Foo {
public void doit() {
System.out.println("bad");
}
public static void main(String[] args) throws Exception {
Bar b = new Bar();
/* Using Foo.class ought to do it right? */
Method m = Foo.class.getDeclaredMethod("doit", new Class[]{});
/* Surely if that didn't do it casting to Foo would? */
m.invoke((Foo)b, new Object[]{});
}
}
Nothing I do using reflection succeeds in printing "good".
My expectation was that using one or more of casting the first argument of invoke to Foo, and/or using Foo.class.getDeclaredMethod instead of Bar.class would be sufficient. Clearly I'm wrong about that, how can I get the desired behaviour still using reflection?
It seems the simplest solution is to use the java.lang.invoke package, which has a method called unreflectSpecial that simulates and invokespecial instruction:
import java.lang.reflect.Method;
import java.lang.invoke.*;
public class Bar extends Foo {
public void doit() {
System.out.println("bad");
}
public static void main(String[] args) throws Throwable {
Bar b = new Bar();
Method m = Foo.class.getDeclaredMethod("doit", new Class[]{});
MethodHandle h = MethodHandles.lookup().unreflectSpecial(m, Bar.class);
h.invoke(b);
}
}
Which does indeed print "good"

How To Set Up PowerMockito To Verify Different Types of Methods Are Called?

Please provide minimal examples of using PowerMockito to test public, public static, private, and private static methods.
Here's an extremely stripped down example ("SSCCE") of using PowerMockito to verify four types of methods have been called from another method: public, public static, private, and private static.
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest(com.dnb.cirrus.core.authentication.TestableTest.Testable.class)
public class TestableTest {
public static class Testable {
public void a() {
b();
c();
d();
e();
}
public void b() {
}
public static void c() {
}
private void d() {
}
private static void e() {
}
}
Testable testable;
// Verify that public b() is called from a()
#Test
public void testB() {
testable = Mockito.spy(new Testable());
testable.a();
Mockito.verify(testable).b();
}
// Verify that public static c() is called from a()
#Test
public void testC() throws Exception {
PowerMockito.mockStatic(Testable.class);
testable = new Testable();
testable.a();
PowerMockito.verifyStatic();
Testable.c();
}
// Verify that private d() is called from a()
#Test
public void testD() throws Exception {
testable = PowerMockito.spy(new Testable());
testable.a();
PowerMockito.verifyPrivate(testable).invoke("d");
}
// Verify that private static e() is called from a()
#Test
public void testE() throws Exception {
PowerMockito.mockStatic(Testable.class);
testable = new Testable();
testable.a();
PowerMockito.verifyPrivate(Testable.class).invoke("e");
}
}
Some pitfalls to be aware of:
PowerMockito and Mockito both implement spy() as well as other methods. Make sure to use the correct class for the situation.
Incorrectly set up PowerMockito tests often pass. Be sure the test can fail when it should (checked for in the above code by commenting out "testable.a()").
Overridden PowerMockito methods take either Class or Object as parameters which are used in static and non-static contexts respectively. Make sure to use the correct type for the context.

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.

Method Parameter Annotations in overridden methods

Is there any way to get the parameter annotations of a method in child class? I tried using the getParameterAnnotations but it not works. I wrote a test class to demonstrate:
public class ParameterAnnotationInheritanceTest {
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.PARAMETER)
#Inherited
public #interface MockAnnotation {
}
public class A {
public void test(#MockAnnotation String value) {
}
}
public class B extends A {
#Override
public void test(String value) {
}
}
#Test
public void TestA() throws NoSuchMethodException, SecurityException {
Method AMethod = A.class.getMethod("test", String.class);
Annotation[][] AMethodParameterAnnotations = AMethod.getParameterAnnotations();
assertTrue(Arrays.asList(AMethodParameterAnnotations[0]).size() > 0);
}
#Test
public void TestB() throws NoSuchMethodException, SecurityException {
Method BMethod = B.class.getMethod("test", String.class);
Annotation[][] BMethodParameterAnnotations = BMethod.getParameterAnnotations();
assertTrue(Arrays.asList(BMethodParameterAnnotations[0]).size() > 0);
}
}
Thanks in advance!
It does not work because the test method in the child class B is not the same test method as in the super class. By overriding it, you have practically defined a new test method that gets called instead of the original one. If you define your child class like this
public class B extends A {
}
and run your code again, it works fine because it is the inherited test method that gets called, which is what you want as far as I understand.

Categories

Resources