I have something like this:
public interface SomeInterface {
public String someMethod(String someArg1, String someArg2);
}
public class SomeInterfaceImpl {
@Override
public String someMethod(String someArg1, String someArg2) {
String response;
// a REST API call which fetches response (need to mock this)
return response;
}
}
public class SomeClass {
public int execute() {
int returnValue;
// some code
SomeInterface someInterface = new SomeInterfaceImpl();
String response = someInterface.someMethod("some1", "some2");
// some code
return returnValue;
}
}
I want to test the execute()
method in SomeClass
using JUnit. Since someMethod(String someArg1, String someArg2)
calls a REST API, I want to mock someMethod
to return some predefined response. But somehow, the real someMethod
gets called instead of returning the predefined response. How do I make it work?
Here is what I have tried using Mockito and PowerMockito:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ SomeInterface.class, SomeInterfaceImpl.class, SomeClass.class })
public class SomeClassTest {
@Test
public void testExecute() {
String predefinedResponse = "Some predefined response";
int expectedReturnValue = 10;
SomeInterfaceImpl impl = PowerMockito.mock(SomeInterfaceImpl.class);
PowerMockito.whenNew(SomeInterfaceImpl.class).withAnyArguments().thenReturn(impl);
PowerMockito.when(impl.someMethod(Mockito.any(), Mockito.any())).thenReturn(predefinedResponse);
SomeClass someClass = new SomeClass();
int actualReturnValue = someClass.execute();
assertEquals(expectedReturnValue, actualReturnValue);
}
}
Mocking is done when you invoke methods of a class that has external communication like database calls or rest calls. Through mocking you can explicitly define the return value of methods without actually executing the steps of the method.
A mock is a fake class that can be examined after the test is finished for its interactions with the class under test. For example, you can ask it whether a method was called or how many times it was called.
Mock is a method/object that simulates the behavior of a real method/object in controlled ways. Mock objects are used in unit testing. Often a method under a test calls other external services or methods within it. These are called dependencies. Once mocked, the dependencies behave the way we defined them.
Here is an example of injecting dependencies without a framework:
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;
interface SomeInterface {
String someMethod(String someArg1, String someArg2);
}
class SomeInterfaceImpl implements SomeInterface {
@Override
public String someMethod(String someArg1, String someArg2) {
String response;
response = "the answer.";// a REST API call which fetches response (need to mock this)
return response;
}
}
class SomeClass {
private final SomeInterface someInterface;
SomeClass(final SomeInterface someInterface) {
this.someInterface = someInterface;
}
public SomeClass() {
this(new SomeInterfaceImpl());
}
public int execute() {
int returnValue;
// some code
String response = someInterface.someMethod("some1", "some2");
returnValue = 42; // some code
return returnValue;
}
}
@RunWith(MockitoJUnitRunner.class)
class SomeClassTest {
private static final String SOME_PREDEFINED_RESPONSE = "Some predefined response";
@Mock
private SomeInterface someInterface;
@InjectMocks
private SomeClass underTest;
@Before
public void setup() {
when(someInterface.someMethod(anyString(), anyString())).thenReturn(SOME_PREDEFINED_RESPONSE);
}
@Test
public void testExecute() {
int expectedReturnValue = 42;
int actualReturnValue = underTest.execute();
assertEquals(expectedReturnValue, actualReturnValue);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With