Spying on an object after cast using Mockito - java

I'm using Mockito to write some unit tests. I ran into the following scenario:
public interface A extends ABase { }
where ABase is an interface with concrete methods in it. I'm using Mockito.spy() on an instance of A, and I want to verify a method foo() declared in ABase is called in a piece of code I'm writing. Inside said code, A is cast to ABase and foo() is called. However, I get a build error (method not found) on the line where I try and verify foo() was called in my test method, like this:
A bar = spy(new A());
//... (function I'm testing is called, A is cast to ABase and foo() called)
verify(bar, times(1)).foo(); //problem line, foo not found
Any suggestions as to what to do? Thanks!
EDIT: there were some errors in my original question. My apologies, it should be fixed now.

Apart from the fact that ABase cannot be a class, because A is an interface and interfaces cannot extend classes:
You're passing A to verify. This shouldn't even compile. Try using bar instead. Mockito expects a mock or spy to be passed to verify so you can verify invocations on a particular argument.

Related

Java unit test check if method is invoked without executing it

I have to test a method which invokes two void methods. I just want to check if the two void methods are invoked or not, but the method must be stubbed.
How do I do it? I tried to implement it using Mockito doThrow method, but not success.
doThrow(new RuntimeException()).when(mockedClass).methodName();
Wanted but not invoked: error
How do I solve my problem?
You can verify only calls in mocked stuff, e.g.
Foo bar = Mockito.mock(Foo.class);
ClassToTest testInstance = new ClassToTest(bar);
testInstance.doStuff();
Mockito.verify(bar, times(1)).someMethod(); // will pass if someMethod of Foo class was called in scope of testInstance.doStuff()
I'm not really sure that you should check actual method calls by expecting an exception. Could you provide some code/a bit more details about the context?
You actually need to use verifyMethod on Mockito. Here is someone who had the same issue. The example shown mocks the object, injects it and then checks to see if it was called or not.
Mockito : how to verify method was called on an object created within a method?

How to mock a method call without actually calling its submethods

I started using JUnits (Mockito) from yesterday. I searched for similar question, but didn't find.
I have a class with method method1() which in turn calls method2().
I don't want to mock method2
I am mocking call to method1(). I was expecting that it would return the custom object(without going ahead and calling method2) which I want. But instead it proceeds and tries to call method2().
class A {
method1() {
//do something.
method2();
}
}
I mocked method1 and return any object (say new Integer(1)).
I dont want method2 to be called. but when I am debugging this Junit. It goes and calls method2. Hence fails.
When using syntax like this:
#Test public void yourTest() {
A mockA = Mockito.mock(A.class, Mockito.CALLS_REAL_METHODS);
when(mockA.method1()).thenReturn(Integer.valueOf(1));
}
then the first thing Java will do is to evaluate when(mockA.method1()), which requires calling mockA.method1() to get a value to pass into when. You don't notice this with other mocks, because Mockito mocks return nice default values, but with spies and CALLS_REAL_METHODS mocks this is a much bigger problem. Clearly, this syntax won't work.
Instead, use the methods beginning with do:
#Test public void yourTest() {
A mockA = Mockito.mock(A.class, Mockito.CALLS_REAL_METHODS);
doReturn(Integer.valueOf(1)).when(mockA).method1();
}
As part of .when(mockA), Mockito will instead return an instance that has no behavior, so the call to method1() never happens on a real instance. do syntax also works with void methods, which makes it more flexible than when(...).thenReturn(...) syntax. Some developers advocate for using doReturn all the time; I prefer thenReturn because it's slightly easier to read, and can also do return type checking for you.
As a side note, prefer Integer.valueOf(1) over new Integer(1) unless you absolutely need a brand new instance. Java keeps a cache of small integers, and this can be faster than allocating a brand new reference if you need to manually box an int into an Integer.
Usually you mock interfaces or abstract classes and provide implementations of abstract methods. In your case you want to substitute the real implementation of a concrete class. This can be achieved via partial mocks.
http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#16

Why method used at mockito object don't show println?

So I want to println some strings. When I do:
MyClass myClass = new MyClass();
myClass.myFunction(myList, path);
It shows me:
somepath/ABC
somepath/DEF
somepath/PQR
But when I do:
MyClass myClass = mock(MyClass.class);
myClass.myFunction(myList, path);
It doesn't show me anything. Is it possible to return these string on mock object?
Since you work with a mock object, you can mock the behavior of its myFunction method, like this:
when(myClass.myFunction()).thenReturn("somepath/ABC");
Note that this will compile, only if the return-type of your method is String.
If you methods return-type is void, then you should not mock a return value, but rather call the real method:
Mockito.doCallRealMethod().when(myClass).myFunction();
which will execute the println statements within the original method implementation. This approach has some pitfalls, though - there's a possibility to get a NullPointerException (or other exceptions) if the method uses some class members, which will be null for the mocked object, unless you set them to refer other mocked objects.
You can use below code to return something when particular method is called on mock object:
when(myClass.myFunction()).thenReturn("somepath/ABC");

mockito mock verify

//Let's import Mockito statically so that the code looks clearer
import static org.mockito.Mockito.*;
//mock creation
List mockedList = mock(List.class);
//using mock object
mockedList.add("one");
mockedList.clear();
//verification
verify(mockedList).add("one");
verify(mockedList).clear();
I don't understand what is the point of this construct? How does it help? How is it different from just calling the functions?
The documentation is rather thin.
Thank you
You wish to test that some method Foo of class A calls some method Bar on an object of class B. In other words, you're testing class A. During your test, you make a mock of class B. Then you pass this mock object to class A somehow (depending on how class A actually works). When your test runs the Foo method of class A, you are expecting the Bar method to get called on your mock of class B. By calling verify for the Bar method, after the test of the Foo method, you can check that the Foo method is actually working correctly - that it calls Bar.
When you do mockedList.add("one"); its performing the operation on the mocked object as same time it remembers your operation. So when you do verify(mockedList).add("one");, it verifies the add was called on mockedList with argument one.
Hope you get the difference.
the verify method of mockito is verify the method invoke times,if the invoke time is 1,we can omit this parameter, see the source code of Mockito Line 1473
public static <T> T verify(T mock) {
return MOCKITO_CORE.verify(mock, times(1));
}
so you code
verify(mockedList).add("one");
//is the same as
verify(mockedList,times(1)).add("one");
is indeed to verify the add method's executed once
Indeed in your example it's obvious, but main idea of verifying methods calls appear during real code testing - imagine that some code performs method call like:
class A{
....
service.doSomething(<some arguments>)
....
}
In order to test it you'll pass mock service object, but sometimes you want to verify particular arguments values passed for that call (or number of calls), so you'll use verify like in your example.

How to mock a single method in java

Is it possible to Mock a single method of a Java class?
For example:
class A {
long method1();
String method2();
int method3();
}
// in some other class
class B {
void someMethod(A a) {
// how would I mock A.method1(...) such that a.method1() returns a value of my
// choosing;
// whilst leaving a.method2() and a.method3() untouched.
}
}
Use Mockito's spy mechanism:
A a = new A();
A aSpy = Mockito.spy(a);
Mockito.when(aSpy.method1()).thenReturn(5l);
The use of a spy calls the default behavior of the wrapped object for any method that is not stubbed.
Mockito.spy()/#Spy
Use the spy() method from Mockito, and mock your method like this:
import static org.mockito.Mockito.*;
...
A a = spy(new A());
when(a.method1()).thenReturn(10L);
Based on Mockito's documentation the accepted answer is not the correct way to Spy real objects.
The right way to do this is to use the following pattern:
doReturn("foo").when(spy).get(0);
Below you can find the snippet from Mockito's about Spying on real objects.
Important gotcha on spying real objects!
Sometimes it's impossible or
impractical to use when(Object) for stubbing spies. Therefore when
using spies please consider doReturn|Answer|Throw() family of methods
for stubbing. Example:
List list = new LinkedList();
List spy = spy(list);
//Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
Mockito does not delegate calls
to the passed real instance, instead it actually creates a copy of it.
So if you keep the real instance and interact with it, don't expect
the spied to be aware of those interaction and their effect on real
instance state. The corollary is that when an unstubbed method is
called on the spy but not on the real instance, you won't see any
effects on the real instance. Watch out for final methods. Mockito
doesn't mock final methods so the bottom line is: when you spy on real
objects + you try to stub a final method = trouble. Also you won't be
able to verify those method as well.
Assuming you are using jmockit:
public void testCase(#Mocked("methodToBeMocked") final ClassBoBeMocked mockedInstance) {
new Expectations() {{
mockedInstance.methodToBeMocked(someParameter); returns(whateverYouLikeItToReturn);
}}
mockedInstance.callSomemethod();
}
You could simply create a subclass of A that overrides method1().

Categories