This question already has answers here:
How to mock void methods with Mockito
(11 answers)
Closed 8 years ago.
I have a Controller class with something like this
public void create(int a, int b){
//do something
}
Now i want to mock the Controller class and call a certain method for exmaple doCustomCreate() when the create Method of my mocked Controller class is called.
My test would ´look something like this
Controller ctrlMock = mock(Controller.class);
//PseudoCode: when(isCalled(ctrlMock.create(a,b)).doCall(doCustomCreate());
I only read about mocking methods with input and return values, so i wondered if this is possible?
Edit: Updated the Question
Just use this API for void methods :
doAnswer(doCustomCreate()).when(ctrlMock).create(a,b);
Or with BDDMockito :
willAnswer(doCustomCreate()).given(ctrlMock).create(a,b);
Where doCustomCreate() returns an Answer (that returns null). Note I used Void just to indicate this answer don't return anything.
public Answer<Void> doCustomCreate() {
return new Answer<Void>() {
public Void answer(InvocationOnMock invocation) {
// your stuff
return null;
}
}
}
Note giving behavior to a mock is somehow a rocky path for maintainability of tests, as it means the tested component is not tested in pure controlled environment / isolation.
So you want to override the mock's behavior for a certain method. The solution for this is using a so-called spy (AKA partial mock) instead of a mock: http://site.mockito.org/mockito/docs/current/org/mockito/Mockito.html#16
Related
This question already has answers here:
Should I test private methods or only public ones? [closed]
(31 answers)
Closed 5 years ago.
Let's say I have a class A, which has two methods. I have to test a method, which internally calls the other method.
class A {
private void method1() {
//some steps to be done
}
public void method3() {
//some steps
}
public void method2() {
method1();
if (XUtil.isSupportRequired) {
method3();
}
}
}
So, If I try to test method2, how to mock method1, as it is not public.
Any help would be appreciated.
I am using junit and mockito.
I think you should try to write black-box tests, that is, it should be of no concern what the class does internally only what is visible through its public interface.
So, test the effects of method 2, either through other methods that should reflect these effects, or through mocked dependencies that are used in the process.
You shouldn't need to mock that other private method.
This question already has answers here:
PowerMock, mock a static method, THEN call real methods on all other statics
(2 answers)
Closed 5 years ago.
I have a utility class that I need to do some unit testing, but within this utility class I have methods that depend on others in that same utility class.
For that I'm using the following dependencies:
jUnit:4.12
Mockito: 2.8
Powermock: 1.7
As it's already evident that I am using Java to perform my code.
Now go to the example code:
public final class AppUtils {
private AppUtils () {
throw new UnsupportedOperationException("This class is not instantiable.");
}
public static int plus(int a, int b) {
return a + b;
}
public static float average(int a, int b) {
return ((float) AppUtils.plus(a, b)) / 2;
}
}
And the unit test:
#RunWith(PowerMockRunner.class)
#PrepareForTest({AppUtils.class})
public class AppUtilsTest {
#Test
public void testPlus() { //This test must be good.
assertEquals(6, AppUtils.plus(4, 2));
}
#Test
public void testAverage() {
PowerMockito.mockStatic(AppUtils.classs);
when(AppUtils.plus(anyInt())).thenReturn(6);
assertEquals(3f, AppUtils.average(4, 3), 1e-2d);
}
}
That way I did my unit test, but this throws me an error because it tells me that the expected result does not correspond to the actual one.
expected: 3.000f
actual: 0
This is because PowerMock by using the mockStatic() method replaces all static implementations for your defines, but if you do not define the result of one static method then it returns 0.
If anyone can help me, I thank you.
UnitTests verify the public observable behavior of the code under test.
The public observable behavior of the CUT includes the return values and the communication with its dependencies.
This means that you treat that other methods as if they where private, just looking at the outcome of the method called.
BTW:
There is no such rule that "utility classes" (in the sense that they provide basic or common functionality) must have static methods only.
That's just a common misconception driven by the habit to name classes with only static methods "utility classes".
It is absolutely OK to make all your utility methods non static and instantiate the class before using it.
Dependency Injection (and not the Singelton Pattern) will help you to have only one instance used all around your program...
I am new to Mockito, please help in understanding the basic.
According to me above code is supposed to print 5 when mocked.add(6,7) gets called , but add() method is not getting called and the code prints 0.. why ? any solution for this code ?
import org.mockito.Mockito;
import static org.mockito.Mockito.*;
class Calc{
int add(int a,int b){
System.out.println("add method called");
return a+b;
}
}
class MockTest{
public static void main(String[] args) {
Calc mocked=mock(Calc.class);
when(mocked.add(2,3)).thenReturn(5);
System.out.println(mocked.add(6,7));
}
}
In order to get result of 5, you have to pass the exact params as when you set up the when..then. Otherwise mockito will return a 'default' value (which is 0 for integer:
What values do mocks return by default?
In order to be transparent and unobtrusive all Mockito mocks by
default return 'nice' values. For example: zeros, falseys, empty
collections or nulls. Refer to javadocs about stubbing to see exactly
what values are returned by default.
If you want to return 5 for any integer then use:
when(mocked.add(Mockito.any(Integer.class),Mockito.any(Integer.class))).thenReturn(5);
A "mock" is just an empty dummy object that simulates behaviour of a "real" object. If you define a behaviour such like when(mocked.add(2,3)).thenReturn(5); you specifically tell this mock what to do, when it receives those exact values.
mocked.add(6,7) will return 0 at that point, since you haven't defined its behaviour for those values and therefore uses a default value. So if you want to cover all possible inputs, you can go with the solution #MaciejKowalski posted and use the generic matchers like Mockito.any(Integer.class).
Still I believe it is not clear how to correctly handle mocks. Mocks are a way of providing external dependencies to a system-under-test without the need to set up a whole dependency tree. The real methods inside that class are usually not called. That's what something like when(mocked.add(2,3)).thenReturn(5); means. It tells the mock to behave like the real dependency without actually having it at hand.
An example could look like this:
public class TestClass {
private ExternalDependency dep;
public void setDep(ExternalDependency dep) {
this.dep = dep;
}
public int calculate() {
return 5 + dep.doStuff();
}
}
public class ExternalDependency {
public int doStuff() {
return 3;
}
}
Now in your test code you can use mocks like this:
#Test
public void should_use_external_dependency() {
// Aquire a mocked object of the class
ExternalDependency mockedDep = Mockito.mock(ExternalDependency.class);
// Define its behaviour
Mockito.when(mockedDep.doStuff()).thenReturn(20);
TestClass sut = new TestClass();
sut.setDep(mockedDep);
// should return 25, since we've defined the mocks behaviour to return 20
Assert.assertEquals(25, sut.calculate());
}
If sut.calculate() is invoked, the method in ExternalDependency should not be really called, it delegates to the mocked stub object instead. But if you want to call the real method of the real class, you could use a Spy instead with Mockito.spy(ExternalDependency.class) or you could do that with when(mockedDep.doStuff()).thenCallRealMethod();
This question already has answers here:
Using an arbitrarily defined method of an anonymous interface
(4 answers)
Closed 9 years ago.
I can imagine some very creative code in Java:
Object thing = new Object() {
public void speak() {
System.out.println("Hi!");
}
};
thing.speak();
Or even, to get the full closure effect, define a Function interface ... you get the idea?
Why doesn't this code work?
i believe you can do it like this :-
new Object() {
public void speak() {
System.out.println("Hi!");
}
}.speak();
may help you .
Not sure about the usefulness in this example, but some type of overriding method(s) on the original declaration is useful and because of it is overriding, you can call the methods. Otherwise in your case, just use the reflection as:
thing.getClass().getMethod("speak").invoke(thing);
and for the overriding method:
Object thing = new Object() {
public void toString() {
System.out.println("Hi! Me inside your mind!");
return "not today!";
}
};
thing.toString();
I use Mockito 1.8.0 so I do not have AnyVararg. Upgrading to later version of Mockito is not on cards from my team at the moment. So please bear with me.
What the class looks like:
public abstract class Parent {
public void someMethod(String a, String b)
{
//.....
}
public void foo(String a, String... b)
{
//.....
}
}
public class Child extends Parent{
public void bar() {
someMethod(a,b);
foo(a,b,c);
methodToFailUsingSpy();
}
}
Unit tests
#Test
public void someTest() {
private spyOfChild = //initialize here;
doReturn("Something")).when(spyOfChild).methodToFailUsingSpy();
/* Tried using this, but did not help.
doCallRealMethod().when(spyOfChild).foo(anyString());
*/
spyOfChild.bar();
}
Problem -
When the spy sees someMethod(), it calls the real method in the abstract class. But when it sees foo(), it tries to find a matching stubbed method i.e control goes to Mockito's MethodInterceptorFilter, since it is not able to find a mock, it throws java.lang.reflect.InvocationTargetException.
I do not want foo() to be mocked. I want the real method to be called like it happens in someMethod(). Can someone explain if it is because of using method with variable length arguments with a spy?
This is a bug in Mockito.
https://groups.google.com/forum/#!msg/mockito/P_xO5yhoXMY/FBeS4Nf4X9AJ
Your example is quite complicated, to reproduce the problem is very simple:
class SimpleClass {
public String varargsMethod(String... in) {
return null;
}
public void testSpyVarargs() {
SimpleClass sc = Mockito.spy(new SimpleClass());
sc.varargsMethod("a", "b");
}
}
Even this will produce the error you describe, and the workaround suggested in the link doesn't work for me.
Unfortunately to get around this you will need to upgrade Mockito. Changing to version 1.9.5 makes the above run fine, plus you get the varargs matchers as you say (although note that your problem isn't to do with matchers but how Mockito handles spied varargs methods).
I don't think there were too many huge changes between 1.8.0 and 1.9.5, it shouldn't be too painful.