Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to replace mock function with new funciton in java

Tags:

java

mockito

I am write UT with Mockito, and I want replace my mock function(which DB select operation)

class DataBaseSelect {
    List<Long> selectDataFromDB(Long key){
         List<Long>  result  = db.select(key);
         return result;
    }
}

with new function (mock db select using map) I wrote in Test class;

class MapSelect {
    List<Long> selectDataFromMap(Long key){
         List<Long> result = map.get(key);
         return result;
    }
}

and I want return the right value with right key input

I try to do this using ArgumentCaptor as below, but it did not work as I want

ArgumentCaptor<Long> argumentCaptor = ArgumentCaptor.forClass(Long.class);
Mockito.when(dataBaseSelect.selectDataFromDB(argumentCaptor.capture())).thenReturn(MapSelect.selectDataFromMap(argumentCaptor.getValue()));
//some thing else here , 

I want when call dataBaseSelect.selectDataFromDB, it will be mock and then return result from MapSelect.selectDataFromMap and argument is passed from dataBaseSelect.selectDataFromDB

like image 266
LiQIang.Feng Avatar asked Nov 29 '17 08:11

LiQIang.Feng


People also ask

How do you mock a method call inside another method in the same class?

We can mock runInGround(String location) method inside the PersonTest class as shown below. Instead of using mock(class) here we need to use Mockito. spy() to mock the same class we are testing. Then we can mock the method we want as follows.

What is the difference between mock and spy?

Mocks are used to create fully mock or dummy objects. It is mainly used in large test suites. Spies are used for creating partial or half mock objects. Like mock, spies are also used in large test suites.

How do you call a real method in mock?

Mockito allows us to partially mock an object. This means that we can create a mock object and still be able to call a real method on it. To call a real method on a mocked object we use Mockito's thenCallRealMethod().


1 Answers

If you need substitute your own implementation of method, you can do something like that:

// create method substitution
Answer<List<Long>> answer = invocation -> mapSelect.selectDataFromMap((Long) invocation.getArguments()[0]);

// Mock method
Mockito.doAnswer(answer).when(dataBaseSelect).selectDataFromDB(anyLong());

Your solution is incorrect, cause captors are intended for method call verification (how many times method was called), example:

// method calling: mockedObject.someMethod(new Person("John"));
//...
ArgumentCaptor<Person> capture = ArgumentCaptor.forClass(Person.class);
verify(mockedObject).someMethod(capture.capture());
Person expected = new Person("John");
assertEquals("John", capture.getValue().getName());

in this example expected that 'someMethod' was called one time and return person "John"

like image 84
EshtIO Avatar answered Oct 21 '22 05:10

EshtIO