I am using mockito for unit testing and I want to skip a line.
// method I am testing
public String doSomeTask(String src, String dst) {
// some code
utils.createLink(src,dst);
// some more code
}
// utils class
public void createLink(String src, String dst) {
// do something
Path realSrc = "/tmp/" + src;
Files.createSymbolicLink(realSrc, dst);
// do something
}
// Test class
#Mock
private Utils utils;
#Test
public void testDoSomeTask() {
// this does not seem to work, it is still executing the createLink method
doNothing.when(utils).createLink(anyString(), anyString());
myClass.doSomeTask(anyString(), anyString());
}
Now, createLink is a void method and its failing during my testing with exception reason AccessDenied to create a directory.
I want to skip the line utils.createLink(src,dst); and continue with next lines. Is there a way I can tell Mockito to do this ?
Assuming that utils variable can be set with a setter, you can spy on your Utils class object and override its createLink() method.
The basic idea is:
Utils utils = new Utils();
Utils spyUtils = Mockito.spy(utils);
doNothing().when(spyUtils).createLink(any(String.class), any(String.class));
Now, set this spyUtils object via setter. Each time createLink is invoked, it does nothing.
You can either mock you utils method to do nothing (with PowerMockito) or change you code so utils method is not static and you can inject the mock instance of utils method to the object you test, something like this:
class ForTesting{
UtilsClass utilsInstance;
ForTesting (UtilsClass utilsInstance) {
this.utilsInstance = utilsInstance;
}
// method you test
public String doSomeTask(String src, String dst) {
// some code
utilsInstance.createLink(src, dst);
// some more code
}
}
#Test
public void test(){
UtilsClass utilsInstance = mock(UtilsClass.class);
ForTesting classForTesting = new ForTesting(utilsInstance);
assertEquals("yourValue",classForTesting.doSomeTask());
}
Mocking with PowerMockito gives some overhead, because you cant override static methods without inheritance, so some native methods needed to modify byte code at runtime.
Related
I'm trying to create a when sentence, but I can't do it well because I don't know how to mock correctly whatever.
I have this code:
public class OperationMovement {
#Value("${operation.check}")
private Boolean needToCheck;
private void checkOperation() {
// Code
if (BooleanUtils.isTrue(needToCheck)) {
// More code
}
}
}
I need to create a test with Mockito, but I don't know how to mock this if else.
I have tried to mock the BooleanUtils this way:
#Mock
BeanUtils beanUtils;
// Code and more testing code
when(booleanUtils.isTrue(anyBoolean())).thenReturn(true);
But this returs an error.
I have tried the following too, but I have the same error:
when(BooleanUtils.isTrue(anyBoolean())).thenReturn(true);
I need to mock that propertie or the BooleanUtils class, but I don't know how.
Quick example usage:
private OperationMovement classUnderTest;
...
#Test
void testOperationIsTrue() {
// For this test case, you are setting it to true
ReflectionTestUtils.setField(classUnderTest,"needToCheck",true);
}
I'm not allowed to post real code, but this is basically what's going on:
We have a class InterfaceOneImpl that implements an interface InterfaceOne and a InterfaceTwoImpl that implements an InterfaceTwo
InterfaceTwoImpl gets instantiated in InterfaceOneImpl, and InterfaceTwoImpl.makeHttpRequest() gets called, but I need to mock this function in my unit tests because I obviously don't want to make http requests in them. makeHttpRequest is a public, non-static function that returns a String
My code does something like this:
public class InterfaceOneImpl implements InterfaceOne{
public String processRequest(...){
...
InterfaceTwo obj = new InterfaceTwoImpl();
obj.makeHttpRequest();
...
}
}
My test class looks like this:
public TestInterfaceOneImpl {
....
#Test
public void testProcessRequest(){
InterfaceOne interfaceOneImpl = new InterfaceOneImpl();
InterfaceTwo mock = PowerMockito.mock(InterfaceTwoImpl.class);
InterfaceTwo.when(mock.processRequest()).thenReturn("zzzz");
PowerMockito.whenNew(RiskValidationRestClientImpl.class).withNoArguments().thenReturn((RiskValidationRestClientImpl) mock);
String reqStr = interfaceOneImpl.processRequest();
//a bunch of failed assertions
}
}
My issue is that processRequest() is not being mocked properly, because the source code version of the method is actually being run rather than the mock. When I step through each line of my unit test in debug mode, I always end up in the body of the makeHttpRequest() function. What am I doing wrong?
My issue is that processRequest() is not being mocked properly, because the source code version of the method is actually being run rather than the mock. When I step through each line of my unit test in debug mode, I always end up in the body of the makeHttpRequest() function.
I think your question is wrong - processRequest, based on your example, is a method on InterfaceOne while mock is an instance of InterfaceTwo.
I assume you meant:
InterfaceTwo.when(mock.makeHttpRequest()).thenReturn("zzzz");
In any case ...
What am I doing wrong?
You think you're mocking something when you're not at all. Let's break down your example:
// First you create an instance of InterfaceOneImpl - OK
InterfaceOne interfaceOneImpl = new InterfaceOneImpl();
// Next you create a mock of InterfaceTwo (I think? I don't use PowerMock) - OK
InterfaceTwo mock = PowerMockito.mock(InterfaceTwoImpl.class);
// Then you tell the mock you created that it should return "zzzz" - OK
InterfaceTwo.when(mock.processRequest()).thenReturn("zzzz");
// Finally you call a method on your instance. YOU DO NOT USE "mock" in
// any way shape or form. As it's defined, "processRequest" creates a NEW
// instance of InterfaceTwo: InterfaceTwo obj = new InterfaceTwoImpl();
// and uses THAT instance. So of course you will always end up with the
// real method being called. You're creating a mock and literally never
// using it.
String reqStr = interfaceOneImpl.processRequest();
To fix: actually use your mock. Either by passing it in the function:
// Pass the object to use as an argument
public String processRequest(InterfaceTwo obj){
...
obj.makeHttpRequest();
...
}
// And then your test:
#Test
public void testProcessRequest() {
InterfaceOne interfaceOneImpl = new InterfaceOneImpl();
InterfaceTwo mock = PowerMockito.mock(InterfaceTwoImpl.class);
InterfaceTwo.when(mock.processRequest()).thenReturn("zzzz");
// NOW you can use the mock
String reqStr = interfaceOneImpl.processRequest(mock);
}
Or by passing it through to the class:
public class InterfaceOneImpl implements InterfaceOne {
public InterfaceOneImpl(InterfaceTwo obj) {
this.obj = obj;
}
public String processRequest(...){
...
obj.makeHttpRequest();
...
}
}
// And then your test
#Test
public void testProcessRequest(){
InterfaceTwo mock = PowerMockito.mock(InterfaceTwoImpl.class);
InterfaceTwo.when(mock.processRequest()).thenReturn("zzzz");
// Now interface one will use the mock to do the request
InterfaceOne interfaceOneImpl = new InterfaceOneImpl(mock);
String reqStr = interfaceOneImpl.processRequest();
//a bunch of failed assertions
}
How to mock methods with void return type?
I implemented an observer pattern but I can't mock it with Mockito because I don't know how.
And I tried to find an example on the Internet but didn't succeed.
My class looks like this:
public class World {
List<Listener> listeners;
void addListener(Listener item) {
listeners.add(item);
}
void doAction(Action goal,Object obj) {
setState("i received");
goal.doAction(obj);
setState("i finished");
}
private string state;
//setter getter state
}
public class WorldTest implements Listener {
#Test public void word{
World w= mock(World.class);
w.addListener(this);
...
...
}
}
interface Listener {
void doAction();
}
The system is not triggered with mock.
I want to show the above-mentioned system state. And make assertions according to them.
Take a look at the Mockito API docs. As the linked document mentions (Point # 12) you can use any of the doThrow(),doAnswer(),doNothing(),doReturn() family of methods from Mockito framework to mock void methods.
For example,
Mockito.doThrow(new Exception()).when(instance).methodName();
or if you want to combine it with follow-up behavior,
Mockito.doThrow(new Exception()).doNothing().when(instance).methodName();
Presuming that you are looking at mocking the setter setState(String s) in the class World below is the code uses doAnswer method to mock the setState.
World mockWorld = mock(World.class);
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
System.out.println("called with arguments: " + Arrays.toString(args));
return null;
}
}).when(mockWorld).setState(anyString());
I think I've found a simpler answer to that question, to call the real method for just one method (even if it has a void return) you can do this:
Mockito.doCallRealMethod().when(<objectInstance>).<method>();
<objectInstance>.<method>();
Or, you could call the real method for all methods of that class, doing this:
<Object> <objectInstance> = mock(<Object>.class, Mockito.CALLS_REAL_METHODS);
Adding to what #sateesh said, when you just want to mock a void method in order to prevent the test from calling it, you could use a Spy this way:
World world = new World();
World spy = Mockito.spy(world);
Mockito.doNothing().when(spy).methodToMock();
When you want to run your test, make sure you call the method in test on the spy object and not on the world object. For example:
assertEquals(0, spy.methodToTestThatShouldReturnZero());
The solution of so-called problem is to use a spy Mockito.spy(...) instead of a mock Mockito.mock(..).
Spy enables us to partial mocking. Mockito is good at this matter. Because you have class which is not complete, in this way you mock some required place in this class.
First of all: you should always import mockito static, this way the code will be much more readable (and intuitive):
import static org.mockito.Mockito.*;
For partial mocking and still keeping original functionality on the rest mockito offers "Spy".
You can use it as follows:
private World world = spy(new World());
To eliminate a method from being executed you could use something like this:
doNothing().when(someObject).someMethod(anyObject());
to give some custom behaviour to a method use "when" with an "thenReturn":
doReturn("something").when(this.world).someMethod(anyObject());
For more examples please find the excellent mockito samples in the doc.
How to mock void methods with mockito - there are two options:
doAnswer - If we want our mocked void method to do something (mock the behavior despite being void).
doThrow - Then there is Mockito.doThrow() if you want to throw an exception from the mocked void method.
Following is an example of how to use it (not an ideal usecase but just wanted to illustrate the basic usage).
#Test
public void testUpdate() {
doAnswer(new Answer<Void>() {
#Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
if (arguments != null && arguments.length > 1 && arguments[0] != null && arguments[1] != null) {
Customer customer = (Customer) arguments[0];
String email = (String) arguments[1];
customer.setEmail(email);
}
return null;
}
}).when(daoMock).updateEmail(any(Customer.class), any(String.class));
// calling the method under test
Customer customer = service.changeEmail("old#test.com", "new#test.com");
//some asserts
assertThat(customer, is(notNullValue()));
assertThat(customer.getEmail(), is(equalTo("new#test.com")));
}
#Test(expected = RuntimeException.class)
public void testUpdate_throwsException() {
doThrow(RuntimeException.class).when(daoMock).updateEmail(any(Customer.class), any(String.class));
// calling the method under test
Customer customer = service.changeEmail("old#test.com", "new#test.com");
}
}
You could find more details on how to mock and test void methods with Mockito in my post How to mock with Mockito (A comprehensive guide with examples)
In Java 8 this can be made a little cleaner, assuming you have a static import for org.mockito.Mockito.doAnswer:
doAnswer(i -> {
// Do stuff with i.getArguments() here
return null;
}).when(*mock*).*method*(*methodArguments*);
The return null; is important and without it the compile will fail with some fairly obscure errors as it won't be able to find a suitable override for doAnswer.
For example an ExecutorService that just immediately executes any Runnable passed to execute() could be implemented using:
doAnswer(i -> {
((Runnable) i.getArguments()[0]).run();
return null;
}).when(executor).execute(any());
Adding another answer to the bunch (no pun intended)...
You do need to call the doAnswer method if you can't\don't want to use spy's. However, you don't necessarily need to roll your own Answer. There are several default implementations. Notably, CallsRealMethods.
In practice, it looks something like this:
doAnswer(new CallsRealMethods()).when(mock)
.voidMethod(any(SomeParamClass.class));
Or:
doAnswer(Answers.CALLS_REAL_METHODS.get()).when(mock)
.voidMethod(any(SomeParamClass.class));
I think your problems are due to your test structure. I've found it difficult to mix mocking with the traditional method of implementing interfaces in the test class (as you've done here).
If you implement the listener as a Mock you can then verify the interaction.
Listener listener = mock(Listener.class);
w.addListener(listener);
world.doAction(..);
verify(listener).doAction();
This should satisfy you that the 'World' is doing the right thing.
If you need to do some operations in the mocked void method, and you need to manipulate the argument that sent to void method; you can combine Mockito.doAnswer with ArgumentCaptor.capture method.
Let's say you have SpaceService that autowires a GalaxyService, which has a void method called someServiceMethod.
You want to write test for one of your method in SpaceService that calls GalaxyService's void method. Your planet is also generated inside SpaceService. So you don't have any chance to mock that.
Here is your sample SpaceService class that you want to write tests for.
class SpaceService {
#Autowired
private GalaxyService galaxyService;
public Date someCoolSpaceServiceMethod() {
// does something
Planet planet = new World();
galaxyService.someServiceMethod(planet); //Planet updated in this method.
return planet.getCurrentTime();
}
}
The GalaxyService.someServiceMethod method expects a planet argument. Does some stuff in the method. See :
GalaxyService {
public void someServiceMethod(Planet planet) {
//do fancy stuff here. about solar system etc.
planet.setTime(someCalculatedTime); // the thing that we want to test.
// some more stuff.
}
}
And you want to test this feature.
Here is an example :
ArgumentCaptor<World> worldCaptor = ArgumentCaptor.forClass(World.class);
Date testDate = new Date();
Mockito.doAnswer(mocked-> {
World capturedWorld = worldCaptor.getValue();
world.updateTime(testDate);
return null;
}).when(galaxyService.someServiceMethod(worldCaptor.capture());
Date result = spaceService.someCoolSpaceServiceMethod();
assertEquals(result, testDate);
In your example you should mock Listener item and use Mockito.verify to check interactions with it
I have the following object which I want to test:
public class MyObject {
#Inject
Downloader downloader;
public List<String> readFiles(String[] fileNames) {
List<String> files = new LinkedList<>();
for (String fileName : fileNames) {
try {
files.add(downloader.download(fileName));
} catch (IOException e) {
files.add("NA");
}
}
return files;
}
}
This is my test:
#UseModules(mockTest.MyTestModule.class)
#RunWith(JukitoRunner.class)
public class mockTest {
#Inject Downloader downloader;
#Inject MyObject myObject;
private final String[] FILE_NAMES = new String[] {"fail", "fail", "testFile"};
private final List<String> EXPECTED_FILES = Arrays.asList("NA", "NA", "mockContent");
#Test
public void testException() throws IOException {
when(downloader.download(anyString()))
.thenThrow(new IOException());
when(downloader.download("testFile"))
.thenReturn("mockContent");
assertThat(myObject.readFiles(FILE_NAMES))
.isEqualTo(EXPECTED_FILES);
}
public static final class MyTestModule extends TestModule {
#Override
protected void configureTest() {
bindMock(Downloader.class).in(TestSingleton.class);
}
}
}
I am overwriting the anyString() matcher for a specific argument. I am stubbing the download() method so that it returns a value for a specific argument and otherwise throws an IOException which gets handled by MyObject.readFiles.
The weird thing here is that the second stub (downloader.download("testFile")) throws the IOException set in the first stub (downloader.download(anyString())). I have validated that by throwing a different exception in my first stub.
Can someone explain me why the exception is thrown when adding an additional stub? I thought that creating a stub does not call the method/other stubs.
The problem is that when you write
when(downloader.download("testFile")).thenReturn("mockContent");
the first thing to be called is downloader.download, which you've already stubbed to throw an exception.
The solution is to use the slightly more versatile stubbing syntax that Mockito provides. This syntax has the advantage that it doesn't call the actual method when stubbing.
doThrow(IOException.class).when(downloader).download(anyString());
doReturn("mock content").when(downloader).download("test file");
I have listed other advantages of this second syntax, in my answer here
I thought that creating a stub does not call the method/other stubs.
This assumption is wrong, because stubbing is calling the mocks methods. Your test methods are still plain java!
Since stubbing for anyString will overwrite stubbing for any specific string you will either have to write two tests or stub for two specific arguments:
when(downloader.download("fail")).thenThrow(new IOException());
when(downloader.download("testFile")).thenReturn("mockContent");
Mockito is a very sophisticated piece of code that tries its best so that you can write
when(downloader.download(anyString())).thenThrow(new IOException());
which means “when the downloaders mock download method is called with anyString argument thenThrow an IOException” (i.e. it can be read from left to right).
However, since the code is still plain java, the call sequence actually is:
String s1 = anyString(); // 1
String s2 = downloader.download(s1); // 2
when(s2).thenThrow(new IOException()); // 3
Behind the scenes, Mockito needs to do this:
register an ArgumentMatcher for any String argument
register a method call download on the downloader mock where the argument is defined by the previously registered ArgumentMatcher
register an action for the previously registered method call on a mock
If you now call
... downloader.download("testFile") ...
the downloader mock checks whether there is an action register for "testFile" (there is, since there is already an action for any String) and accordingly throws the IOException.
Your 2nd mock statement is getting overriden by the first mock statement (because both mock statements are passing a String argument). If you want to cover try as well as catch back through your mock test then write 2 different test cases.
I need to write unit tests against a pre-existing code base using TestNG, Mockito and now PowerMockito, to test private and static methods more easily. I am currently trying to write a test against a private void method in a class that we are testing, but am unable to figure it out. In the normal PowerMock API there are methods called replayAll(), verifyAll(), and expectLastCalled(), which are suitable for most purposes. I just can't find good docs that explain how to do it the PowerMockito way. Any explanations or insights on this would be much appreciated.
Method to test:
private void pVMethod(Type param) throws Exception {
param.setA(StaticClass.methodA().toString());
param.setB(StaticClass.methodB().toString());
// getMemo(String label) is in a public class in same package
param.setC(getMemo("memo.provider"));
param.setD(getMemo("memo.item"));
try {
param.setTimestamp(DataTypeFactory.newInstance().newXMLGregorianCalendar(newjava.util.GregorianCalendar()));
} catch (SomeException e) {
...
throw new Exception();
}
}
test attempt:
#Test(expectedExceptions = Exception.class)
public void pVMethod() throws Exception {
TestClass testMock = mock(TestClass.class);
Exception exception = mock(Exception.class);
// StaticClass staticClassMock = mock(StaticClass.class); ??
mockStatic(StaticClass.class);
// when(..) and thenReturn(..) are static imports from PowerMockito library
when(StaticClass.methodA()).thenReturn("stubStringA");
when(StaticClass.methodB()).thenReturn("stubStringB");
doThrow(exception).when(param).setTimestamp(Mockito.any(XMLGregorianCalendar.class));
// Docs say method name can be inferred via reflection
Whitebox.invokeMethod(tested, event);
// this is where things are hairy. testedSpy is defined at the top level
verifyPrivate(testedSpy).pVMethod(testMock);
}
Ok, here is the answer:
In PowerMockito, if you want to verify the behavior of a private void method you use the verifyPrivate() method, but you have to do it like this:
verifyPrivate(tested).invoke("privateMethodName", argument);
Notice the use of the invoke method, missing from the last line of the OP.
NOTE: You do not have to use a doNothing().when(mock.privateMethod()) statement, because void methods in mock objects don't do anything by default.
example taken from here