Verify a function is called from another function mockito - java

I have a class in which I would like to verify method calls
Here is a representation of my class :
public class MyClass {
public void method1(String id) {
MyClass inst = this.getParticularInstance(id);
if(inst != null) {
inst.doSomething();
}
}
public MyClass getParticularInstance(String id) {
// return a particular object or null
}
public void doSomething(String id) {
// do something
}
}
In particular, I would like to make sure that when I call method1, getParticularInstance is called, and depending of the result, doSomething is called or not.
Is it possible to test such a code with Mockito, and if yes is it the right way ?
Thank you

Spy the MyClass and use verify() to verify the method invocation
#RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
private MyClass myClass;
#Before
public void setUp() {
myClass = spy(new MyClass());
}
public void testMethod1() {
// Arrange
String id = "id1";
// Act
myClass.method1(id);
// Assert
verify(myClass).getParticularInstance(id);
}
}

Related

How to verify a method was called inside another method with Mockito

I'm fairly new to Mockito, and I've been looking for a way to verify that if I call the filter() method with the right string, that the foo method will get called once.
public class A
{
private final Config _config;
public A(Config config) { _config = config; }
public void filter(String str)
{
if(str.startsWith("a"))
{
if(str.contains("z"))
{
foo(config.getName());
}
}
}
private void foo(String bar)
{
(...)
}
}
Here is my current code:
#Test
public void testOne()
{
Config config = new Config(configFile);
A a = Mockito.spy(new A(config));
a.filter("abcz");
verify(a, times(1)).foo(someString);
}
Try to be more generic while such a test. If you don't need to specify what exactly argument should by passed then just use any():
import static org.mockito.ArgumentMatchers.any;
verify(a).foo(any(String.class));

How to stub method using Mockito in java

I have a singleton class S which implements an interface I.
Singleton class has a method A which inturn calls method B.
I have to test method A.
This is my singleton Class
public class S implements I{
private static S INSTANCE = new S();
public static I getInstance(){
return INSTANCE;
}
public String methodA(){
methodB();
}
}
This is how my method looks in the test class.
public void testMethodA(){
S so = S.getInstance();
S spy = Mockito.spy(so);
Mockito.doReturn(something).when(spy).methodB(); // I have to cut the dependency of this method B, hence will stub this
String exp_value = 'X';
assertEquals(exp_value,spy.methodA);
}
The issue is, actual method B is called instsead of the stub and hence my test fails.
Could anyone help and let me know if im doing anything wrong here.
Your code with a few modifications compiles and runs as expected. Here is a self contained running example.
public class StackOverflow59960713 {
public interface I {
String methodA();
}
public static class S implements I {
private static S INSTANCE = new S();
public static I getInstance() {
return INSTANCE;
}
public String methodA() {
return methodB();
}
public String methodB() {
return "abc";
}
}
#Test
public void testMethodA() {
S so = (S) S.getInstance(); <== getInstance() returns I not S
S spy = Mockito.spy(so);
Mockito.doReturn("123").when(spy).methodB();
String exp_value = "123";
assertEquals(exp_value, spy.methodA()); <=== methodA() not methodA
}
}

Is it possible to set tested class' method's return value in JUnit?

Say, there's the following class to be tested:
public class MyClass {
public void method1() {
...
String str = method3()
...
}
public int method2() {...}
private String method3() {...}
}
I'm writing MyClassTest.java with JUnit. I want method3() to return a value that I have assigned, not execute the method itself. I can only use Mockito.
Is it possible?
If yes, how do I do it?
With just Mockito you cannot mock a private method.
But you could refactor your code to extract method3() in another class as a public method that you could use as dependency of MyClass. In this way method3() is naturally mockable.
public class MyClass {
private Foo foo;
public MyClass(Foo foo){
this.foo = foo;
}
public void method1() {
...
String str = foo.method3()
...
}
public int method2() {...}
}
public class Foo {
public String method3() {...}
}
Now mock that in the unit test :
#Mock
Foo fooMock;
MyClass myClass;
#BeforeEach
void init(){
myClass = new MyClass(fooMock);
}
#Test
public void method1(){
Mockito.when(fooMock.method3()).thenReturn("dummy value");
// call method1()
// do assertions
}
You can't do it with Mockito, but you can with JMockit. Your test would look like this:
#RunWith(JMockit.class)
public class JMockitTest {
#Tested
private MyClass myClass;
#Before
public void setUp(){
myClass = new MyClass();
}
#Test
public void testMethod1(){
new MockUp<MyClass>() {
#Mock
String method3() {
return "dummy value";
}
};
myClass.method1();
// do assertions
}
}
You can read the documentation about this feature, called faking, here.

How to change return value of mocked method with no argument on each invocation?

I want mocked object return different values on each its method call. But the method has no parameter. Here is an example:
public class MyClass {
public double getValue() {
return 0;
}
}
public class IteratorClass {
MyClass myClass;
public IteratorClass(MyClass myClass) {
this.myClass = myClass;
}
public void iterate() {
for (int i = 0; i < 5; i++) {
System.out.println("myClass.getValue() = " + myClass.getValue());
}
}
}
public class IteratorClassTest {
private MyClass myClass;
private IteratorClass iteratorClass;
#Before
public void setUp() throws Exception {
myClass = mock(MyClass.class);
iteratorClass = spy(new IteratorClass(myClass));
}
#Test
public void testIterate() throws Exception {
when(myClass.getValue()).thenReturn(10d);
when(myClass.getValue()).thenReturn(20d);
when(myClass.getValue()).thenReturn(30d);
when(myClass.getValue()).thenReturn(40d);
when(myClass.getValue()).thenReturn(50d);
iteratorClass.iterate();
}
}
I'm spying here an IteratorClass and mocking MyClass. I want getValue() method return different value on each call. But it is returning last value set on mocked object. If getValue() method has some parameter like getValue(int arg), then could return different value according to the parameter. (e.g. getValue(0) -> return 10, getValue(1) -> return 20 etc).
But how to be when method has no parameters?
You can either specify the consecutive return values as chained method calls (aka fluent API):
#Test
public void testIterate() throws Exception {
when(myClass.getValue()).thenReturn(10d)
.thenReturn(20d)
.thenReturn(30d)
.thenReturn(40d)
.thenReturn(50d);
iteratorClass.iterate();
}
or as VarAgs:
#Test
public void testIterate() throws Exception {
when(myClass.getValue()).thenReturn(10d,20d,30d,40d,50d);
iteratorClass.iterate();
}
either way that last one will be retuned for any further call to the method.
According to answer from Using Mockito with multiple calls to the same method with the same arguments you should modify your code:
...
#Test
public void testIterate() throws Exception {
when(myClass.getValue()).thenReturn(10d, 20d, 30d, 40d, 50d);
iteratorClass.iterate();
}
...

How to initialize mocked object?

Lets say I have the following code:
Mocked object class
public class SomeClass {
private Foo someField;
public SomeClass {
someField = new Foo();
}
public Foo getSomeField { return someField; }
public void getSomething() {}
public boolean doSomething(Object object) {}
}
Next I have test suite
public class TestSuite {
private ClassToTest classToTest;
private SomeClass mock;
#Before
public void setUp() {
classToTest = new ClassToTest();
mock = EasyMock.createMock(SomeClass.class);
}
#Test
public void testMethod() throws Exception {
mock.getSomething();
EasyMock.replay(mock);
classToTest.methodToTest(mock); //Where methodToTest accepts SomeClass and int
EasyMock.verify(mock);
}
}
And method which is being tested
public void methodToTest(SomeClass a) {
//Logic here
Foo b = a.getSomeField();
b.do(); // <--- null pointer exception here because someField isn't initialized
a.getSomething(); // <--- thing I want to test if it is being called, but can't due to exception prior to this line
//Logic after
}
I am stuck.. So yea basically SomeClass isn't initialized like I wanted to. Is there any workaround? Or maybe any other frameworks which can do something like that?
Your methodToTest calls a.getSomeField(), but the setup part of your test doesn't expect that call. You want something like:
Foo foo = new Foo();
EasyMock.expect(mock.getSomeField()).andReturn(foo);
Or to stub the call:
Foo foo = new Foo();
EasyMock.expect(mock.getSomeField()).andStubReturn(foo);
(before your call to mock.getSomething()).
See this question for the differences between andReturn and andStubReturn.

Categories

Resources