I need to test a few very simple classes. The first one is Child class:
public class Child extends Parent {
public int newMethod() {
anotherMethod();
protectedMethod();
return protectedMethodWithIntAsResult();
}
public void anotherMethod() {
// method body no so important
}
}
Than I have a Parent class:
public class Parent {
protected void protectedMethod() {
throw new RuntimeException("This method shouldn't be executed in child class!");
}
protected int protectedMethodWithIntAsResult() {
throw new RuntimeException("This method shouldn't be executed in child class!");
}
}
And finally my test class with single test method:
#PrepareForTest({Child.class, Parent.class})
public class ChildTest extends PowerMockTestCase {
#Test
public void test() throws Exception {
/** Given **/
Child childSpy = PowerMockito.spy(new Child());
PowerMockito.doNothing().when(childSpy, "protectedMethod");
PowerMockito.doReturn(100500).when(childSpy, "protectedMethodWithIntAsResult");
/** When **/
int retrieved = childSpy.newMethod();
/** Than **/
Assert.assertTrue(retrieved == 100500);
Mockito.verify(childSpy, times(1)).protectedMethod();
Mockito.verify(childSpy, times(1)).protectedMethodWithIntAsResult();
Mockito.verify(childSpy, times(1)).anotherMethod(); // but method was invoked 3 times.
}
}
I have a problem with last verification. Program throws an exception:
org.mockito.exceptions.verification.TooManyActualInvocations:
child.anotherMethod();
Wanted 1 time:
-> at my.project.ChildTest.test(ChildTest.java:30)
But was 3 times. Undesired invocation:
And I don't understand why. Any ideas why it happens?
The problem is happening when you call int retrieved = childSpy.newMethod() because in there you are calling anotherMethod() and protectedMethod().
Mockito assumes that you will be calling each method only ones but newMethod internally calls protectedMethod and anotherMethod and anotherMethod has already been called once.
If you remove the call to either newMethod or anotherMethod the test will run fine.
Related
Is there any way, using Mockito or PowerMockito, to intercept calls to non-static methods of an object, or at least of a singleton object?
An example is provided by the following classes:
public class Singleton {
private static Singleton INSTANCE = null;
private Singleton(Object parameter) {}
public static Singleton getInstance(Object parameter) {
if (INSTANCE == null) {
INSTANCE = new Singleton(parameter);
}
return INSTANCE;
}
public String process(String a, String b) {
return (a + b);
}
// Other methods
}
public class Foreign {
private Foreign() {}
public static void main(String[] args) {
System.out.println(Singleton.getInstance(new Object()).process("alpha", "beta"));
}
}
The Singleton object is created in a Foreign class, outside the control of some test code (not shown above). Neither of these two classes can be modified. The objective is to intercept calls to the non-static process() method in the test code so that, for certain values, a different result is returned, e.g. the call
Singleton.getInstance(new Object()).process("alpha", "beta");
mocked to return "alpha-beta" instead of the expected "alphabeta".
One solution could be intercepting the Singleton.getInstance() method to instantiate a custom subclass of the Singleton, e.g. using
public class SubSingleton extends Singleton {
public SubSingleton(Object parameter) {
super(parameter);
}
public String process(String a, String b) {
if ("alpha".equals(a) && "beta".equals(b)) {
return a + "-" + b;
}
return super.process(a + b);
}
}
Then, calls to the Singleton.process() method would be intercepted as in:
Object parameter = new Object();
PowerMockito.doReturn(new SubSingleton(parameter)).when(Singleton.class, "getInstance", parameter);
However, the Singleton class above only provides a private constructor, so it cannot be extended. Using PowerMockito.whenNew() to return a partial mock (spy) will also not work, since the Singleton class does not provide a no-args constructor.
Can the desired mocking be implemented in any other way? Can it be done for non-singleton classes?
Firstly, you can use whenNew for objects with constructor with some params:
#RunWith(PowerMockRunner.class)
#PrepareForTest(Singleton.class)
public class SingletonPrivateNewTest {
#Mock
Singleton singletonMock;
#Before
public void setUp() throws Exception {
PowerMockito.whenNew(Singleton.class)
.withAnyArguments()
.thenReturn(singletonMock);
}
#Test
public void testMockNew() throws Exception {
Mockito.when(singletonMock.process(anyString(), anyString())).thenReturn("sasa");
Foreign.main(new String[0]);
}
}
Secondly, why not stub getInstance instead of new:
#RunWith(PowerMockRunner.class)
#PrepareForTest(Singleton.class)
public class SingletonPrivateNewTest {
#Test
public void testMockNew() {
PowerMockito.mockStatic(Singleton.class);
Singleton singletonMock = Mockito.mock(Singleton.class);
PowerMockito.when(Singleton.getInstance(any())).thenReturn(singletonMock);
Mockito.when(singletonMock.process(anyString(), anyString())).thenReturn("sasa");
Foreign.main(new String[0]);
}
}
Thirdly, to intercept the process method:
create real singleton
create a mock singleton
mock static getInstance to return the mock. NOTE: you must call mockStatic after getting real instance.
use thenAnswer to check the arguments on process call
return desired answer if they match desired pattern
else call real method on real singleton
#RunWith(PowerMockRunner.class)
#PrepareForTest(Singleton.class)
public class SingletonPrivateNewTest {
#Test
public void testMockNew() {
var singletonReal = Singleton.getInstance(new Object());
var singletonMock = Mockito.mock(Singleton.class);
PowerMockito.mockStatic(Singleton.class);
PowerMockito.when(Singleton.getInstance(any())).thenReturn(singletonMock);
Mockito.when(singletonMock.process(anyString(), anyString())).thenAnswer((args) -> {
String a = args.getArgument(0);
String b = args.getArgument(1);
if ("alpha".equals(a) && "beta".equals(b)) {
return "sasa";
} else {
return singletonReal.process(a, b);
}
});
Foreign.main(new String[0]);
}
}
And finally, use a spy instead of a mock
#RunWith(PowerMockRunner.class)
#PrepareForTest(Singleton.class)
public class SingletonPrivateNewTest {
#Test
public void testMockNew() {
var singletonReal = Singleton.getInstance(new Object());
var singletonMock = Mockito.spy(singletonReal);
PowerMockito.mockStatic(Singleton.class);
PowerMockito.when(Singleton.getInstance(any())).thenReturn(singletonMock);
Mockito.when(singletonMock.process("alpha", "beta")).thenReturn("sasa");
// NOTE: real method is called for other args
Foreign.main(new String[0]);
}
}
I have a class under test which contains a method which has an inner anonymous class. One of the methods in the anonymous class calls a method from the class under test, but Mockito doesn't seem to realize this.
public class ClassUnderTest {
Dependency dependency;
public ClassUnderTest(Dependency d) {
dependency = d;
}
public void method() {
dependency.returnsObservable().observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io()).subscribe(new Observer<SupportClass> {
/* Other methods omitted */
public void onComplete() {
outerMethod();
})
}
public void outerMethod() {
blah;
}
}
My test code:
public class TestClass {
ClassUnderTest underTest;
Dependency dependency;
#Before
public void setUp() throws Exception {
dependency = Mockito.mock(Dependency.class);
underTest = Mockito.spy(new ClassUnderTest(dependency));
}
#Test
public void method() throws
Mockito.when(dependency.returnObservable()).thenReturn(Observable.just(new SupportClass());
Mockito.doNothing().when(underTest).outerMethod();
underTest.method();
Mockito.verify(underTest).outerMethod();
}
}
For some reason that I can't seem to figure out, Mockito can't detect that outerMethod() is being called, even though I have manually verified by stepping through line by line in the debugger. I have also verified that the call to the dependency object returns the proper observable with the correct content, and the onComplete() and outerMethod() methods do get called. I'm just confused why Mockito doesn't detect it as such.
This is the error that it spits out:
Wanted but not invoked:
classUnderTest.outerMethod();
-> at (file and line number)
However, there was exactly 1 interaction with this mock:
classUnderTest.method();
-> at (file and line number)
Is there anything obvious I'm missing?
You're changing between schedulers so it can cause some issues when testing (your code may reach the verify method before the actual method is invoked
Check this article explaining how to test asynchronous code with RxJava and Mockito
TL;DR
Add a TestRule that set all schedulers to trampoline so it behaves synchronously:
public class TrampolineSchedulerRule implements TestRule {
#Override
public Statement apply(final Statement base, Description d) {
return new Statement() {
#Override
public void evaluate() throws Throwable {
RxJavaPlugins.setIoSchedulerHandler(
scheduler -> Schedulers.trampoline());
RxJavaPlugins.setComputationSchedulerHandler(
scheduler -> Schedulers.trampoline());
RxJavaPlugins.setNewThreadSchedulerHandler(
scheduler -> Schedulers.trampoline());
RxAndroidPlugins.setInitMainThreadSchedulerHandler(
scheduler -> Schedulers.trampoline());
try {
base.evaluate();
} finally {
RxJavaPlugins.reset();
RxAndroidPlugins.reset();
}
}
};
}
}
My class structure is as follows:
public class MyParentClass {
void doSomethingParent() {
System.out.println("something in parent");
}
}
public class MyClass extends MyParentClass {
protected String createDummyRequest(Holder myHolder) {
//...
super.doSomethingParent();//I want to avoid this
//...
callingDB();
return "processedOutput";
}
private void callingDB() {
System.out.println("Calling to DB");
}
}
Then my unit test:
public class UnitTest {
public void testCreateDummyRequest() {
//create my mock holder
Holder mockHolder = new Holder();
MyClass mockObj = Mockito.mock(MyClass.class);
//mock doSomethingParent()
//mock callingDB()
//as mockObj is a fully mock, but I need to run my real method
//Mockito.when(mockObj.createDummyRequest(mockHolder)).thenCallRealMethod();
mockObj.createDummyRequest(mockHolder);
//Problem: doSomethingParent() is getting called though I have mocked it
}
}
How do I prevent the calling of the super.doSomethingParent() in my method? (method which I am writing my test)
With this class structure mocking and testing is real hard. If possible, I'd advice to change the structure as in mist cases a class structure that's hard to mock and test is equally hard to extend and maintain.
So if you could change your class structure to something similar to:
public class MyClass {
private DoSomethingProvider doSomethingProvider;
private DbConnector dbConnector;
public MyClass (DoSomethingProvider p, DbConnector c) {
doSomethingProvicer = p;
dbConnector = c;
}
protected String createDummyRequest(Holder myHolder){
//...
doSomethingProvider.doSomethingParent();
//...
dbConnector.callingDB();
return "processedOutput";
}
}
Then you could easily create your instance with mocks of DoSomethingProvider and DbConnector and voila....
If you can't change your class structure you need to use Mockito.spy instead of Mockito.mock to stub specific method calls but use the real object.
public void testCreateDummyRequest(){
//create my mock holder
Holder mockHolder = new Holder();
MyClass mockObj = Mockito.spy(new MyClass());
Mockito.doNothing().when(mockObj).doSomething();
mockObj.createDummyRequest(mockHolder);
}
Note: Using the super keyword prevents Mockito from stubbing that method call. I don't know if there is a way to stub calls to super. If possible (as in you didn't override the parent method in your class), just ommit the keyword.
I faced similar issue, so I find out that using spy() can hepld.
public class UnitTest {
private MyClass myObj;
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
myObj= spy(new MyClass());
}
#Test
public void mockedSuperClassMethod(){
doNothing().when((MyParentClass )myObj).doSomethingParent();
//...
}
}
This approach works for me.
I found another approach, which turned out to be very useful in my case.
In the case I had, I needed to create a new class extending another, which included a very complex (legacy code) protected final method. Due to the complexity, it wasn't really possible to refactor to use composition, so here's what I came up with.
Let's say I have the following:
abstract class Parent {
public abstract void implementMe();
protected final void doComplexStuff( /* a long parameter list */) {
// very complex legacy logic
}
}
class MyNewClass extends Parent {
#Override
public void implementMe() {
// custom stuff
doComplexStuff(/* a long parameter list */); // calling the parent
// some more custom stuff
}
}
Here's how I rearranged this code:
abstract class Parent {
public abstract void implementMe();
protected final void doComplexStuff( /* a long parameter list */) {
// very complex legacy logic
}
}
interface ComplexStuffExecutor {
void executeComplexStuff(/* a long parameter list, matching the one from doComplexStuff */);
}
class MyNewClass extends Parent {
private final ComplexStuffExecutor complexStuffExecutor;
MyNewClass() {
this.complexStuffExecutor = this::doComplexStuff;
}
MyNewClass(ComplexStuffExecutor complexStuffExecutor) {
this.complexStuffExecutor = complexStuffExecutor;
}
#Override
public void implementMe() {
// custom stuff
complexStuffExecutor.doComplexStuff(/* a long parameter list */); // either calling the parent or the injected ComplexStuffExecutor
// some more custom stuff
}
}
When creating instance of MyNewClass for "production" purposes, I can use the default constructor.
When writing unit tests, however, I'd use the constructor, where I can inject ComplexStuffExecutor, provide a mock there and only test my custom logic from MyNewClass, i.e.:
class MyNewClassTest {
#Test
void testImplementMe() {
ComplexStuffExecutor complexStuffExecutor = Mockito.mock(ComplexStuffExecutor.class);
doNothing().when(complexStuffExecutor).executeComplexStuff(/* expected parameters */);
MyNewClass systemUnderTest = new MyNewClass(complexStuffExecutor);
// perform tests
}
}
At first glance, it seems like adding some boilerplate code just to make the code testable. However, I can also see it as an indicator of how the code should actually look like. Perhaps one day someone (who would find courage and budget ;) ) could refactor the code e.g. to implement the ComplexStuffExecutor with the logic from doComplexStuff from Parent, inject it into MyNewClass and get rid of inheritance.
Here is how it can be done
public class BaseController {
public void method() {
validate(); // I don't want to run this!
}
}
public class JDrivenController extends BaseController {
public void method(){
super.method()
load(); // I only want to test this!
}
}
#Test
public void testSave() {
JDrivenController spy = Mockito.spy(new JDrivenController());
// Prevent/stub logic in super.method()
Mockito.doNothing().when((BaseController)spy).validate();
// When
spy.method();
// Then
verify(spy).load();
}
Source: https://blog.jdriven.com/2013/05/mock-superclass-method-with-mockito/
Is there a way to always execute a function before any other function of a class is called?
I have a class where I need to refresh some fields always before any function is called:
public class Example {
private int data;
public void function1(){
}
public void function2(){
}
//#BeforeOtherFunction
private void refresh(){
// refresh data
}
}
Because it seems to be bad programming, I don't want to call refresh at the beginning of every other function. Since other persons are going to work on this project as well, there would be the danger, that somebody extends the calls and doesn't call refresh.
JUnit has a solution for this with the #Before-Annotation. Is there a way to do this in other classes as well?
And by the way: If you know a programming pattern wich solves this problem in another way than executing a function everytime any function is called, that would be very helpful, too!
Use a dynamic proxy in which you can filter to those methods before which your specific "before" method should be called. And call it in those cases before dispatching the call. Please see the answer from How do I intercept a method invocation with standard java features (no AspectJ etc)?
UPDATE:
An interface is needed to be separated for the proxy. The refresh() method cannot remain private. It must be public and part of the interface (which is not nice here) to be able to be called from the proxy.
package CallBefore;
public interface ExampleInterface {
void function1();
void function2();
void otherFunction();
void refresh();
}
Your class implements that interface:
package CallBefore;
public class Example implements ExampleInterface {
#Override
public void function1() {
System.out.println("function1() has been called");
}
#Override
public void function2() {
System.out.println("function2() has been called");
}
#Override
public void otherFunction() {
System.out.println("otherFunction() has been called");
}
#Override
public void refresh() {
System.out.println("refresh() has been called");
}
}
The proxy which does the trick. It filters the needed methods and calls refresh().
package CallBefore;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ExampleProxy implements InvocationHandler {
private ExampleInterface obj;
public static ExampleInterface newInstance(ExampleInterface obj) {
return (ExampleInterface) java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), new ExampleProxy(obj));
}
private ExampleProxy(ExampleInterface obj) {
this.obj = obj;
}
#Override
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Object result;
try {
if (m.getName().startsWith("function")) {
obj.refresh();
}
result = m.invoke(obj, args);
} catch (InvocationTargetException e) {
throw e.getTargetException();
} catch (Exception e) {
throw new RuntimeException("unexpected invocation exception: " + e.getMessage());
}
return result;
}
}
The usage:
package CallBefore;
public class Main {
public static void main(String[] args) {
ExampleInterface proxy = ExampleProxy.newInstance(new Example());
proxy.function1();
proxy.function2();
proxy.otherFunction();
proxy.refresh();
}
}
Output:
refresh() has been called
function1() has been called
refresh() has been called
function2() has been called
otherFunction() has been called
refresh() has been called
This may not solve your exact problem but at least could be a starting point if you are allowed considering a re-design. Below is a simple implementation but with some small touches I believe you can achieve a more elegant solution. BTW, this is called Dynamic Proxy Pattern.
First thing you need is an interface for your class.
public interface Interface {
void hello(String name);
void bye(String name);
}
public class Implementation implements Interface {
#Override
public void hello(String name) {
System.out.println("Hello " + name);
}
#Override
public void bye(String name) {
System.out.println("Bye " + name);
}
}
Then java.lang.reflect.Proxy class comes to help. This class is able to create an instance for a given interface at runtime. It also accepts an InvocationHandler which helps you to capture method calls and looks like this.
public class InvocationHandlerImpl implements InvocationHandler {
private final Object instance;
public InvocationHandlerImpl(Object instance) {
this.instance = instance;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result;
try {
System.out.println("Before");
result = method.invoke(instance, args);
System.out.println("After");
} catch (Exception e){
e.printStackTrace();
throw e;
} finally {
System.out.println("finally");
}
return result;
}
}
After all your client code will look like this.
Interface instance = new Implementation();
Interface proxy = (Interface)Proxy.newProxyInstance(
Interface.class.getClassLoader(),
new Class[] { Interface.class },
new InvocationHandlerImpl(instance));
proxy.hello("Mehmet");
proxy.bye("Mehmet");
Output for this code is
Before
Hello Mehmet
After
finally
Before
Bye Mehmet
After
finally
I would define getters for every field and do the refreshment inside the getter. If you want to avoid unrefreshed access to your private fields at all, put them in a superclass (together with the getters which call refresh).
Depending on your project structure, it may be also sensible to introduce a separate class for all data that is regularly refreshed. It can offer getters and avoid that anyone accesses the non-refreshed fields.
Not in Java SE, but if you are using Java EE, you could use interceptors.
For standalone applications, you could consider using a bytecode manipulation framework, like javassist.
You can have a protected getter method for data. Access getData method instead of using data field. Child classes will see only getData and will have updated data every time.
public class Example {
private int data;
public void function1(){
}
public void function2(){
}
protected int getData(){
refresh();
return data;
}
//#BeforeOtherFunction
private void refresh(){
// refresh data
}
}
It is better to write another method which will be made protected(accessible to the child classes) which will call first the refresh method and then call the function.
This way the data would be refreshed before the function is called everytime(As per your requirement).
eg:
protected void callFunction1(){
refresh();
function();
}
Thanks,
Rajesh
You should use Decorator in this case. Decorator is a good choice for something like interceptor. Example here: https://msdn.microsoft.com/en-us/library/dn178467(v=pandp.30).aspx
Ok so I'm stuck with Mockito again. Here's the situation:
I've a super class, and a subclass:
class Parent {
protected void insertData() {
// Here is some database related stuff
someObject.storeData();
}
}
class Child extends Parent {
private String name;
public void printHierarchy(int x) {
if (x > 1) {
insertData()
} else {
System.out.println("Child");
}
}
}
And in my unit test class, I'm testing Child class printHierarchy() method:
#RunWith(SpringJUnit4ClassRunner.class)
public class ChildTest {
#InjectMocks // To inject mock objects
private Child child = new Child();
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
// This is where the issue is
doNothing().when(child).insertData();
}
#Test
public void testPrintHierarchy() {
child.printHierarchy(5);
// Here also
verify(child, times(1)).insertData();
}
}
So the issue is, how do I verify if insertData() method was called from Child#printHierachy()?
When I try the above code, I get the error as:
Argument passed to when() is not a mock!
Of course, child is not a mock. I'm testing that class. But how do I resolve this issue?
No I haven't found any duplicate of this. One question was pretty similar though, but it didn't help me.
You need to use spy() for that. The following code works:
public final class Bin
{
#Test
public void spyMe()
{
final Child c = spy(new Child());
doNothing().when(c).printParent();
c.printHierarchy(1);
verify(c).printParent();
}
}
class Parent {
protected void printParent() { System.exit(0);}
}
class Child extends Parent {
private String name;
public void printHierarchy(int i) {
if (i > 0)
printParent();
}
}
I think you need to use a spy for Child instead of a mock.
Whether method printHierachy() calls method printParent() is surely an implementation detail of method printHierachy(), and so should not be tested for. Unit tests should check that a method has the required outputs.
For printing methods, checking the format of the printed output would do. For a method that updates a data-base, check that the data-base contains the expected values. For a method that manipulates a domain-model object in a specified manner, check that the domain object is in the correct state. And so on.
I think the mistake may be conceptual. If Child extends Parent, then the methods of Parent are part of the implementation, i.e. the System Under Test.
If the Parent needs to be mocked independently of the Child, then maybe you should use composition instead of inheritance:
public class Child {
private Parent parent;
public void printHierarchy() {
parent.printParent();
}
// setters/getters
}
Now the Parent is mockable and you can test whether printParent() was called or not.
If the class hierarchy is conceptually correct, then you should not need to test internal implementation details (i.e. that the interface/public method calls some other). You do not care about implementation details.