How to replace mock function with new funciton in java

I am writing UT with Mockito and I want to replace my mock function (what DB select operation)

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

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

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

and I want to return the correct value with the correct key entry

I am trying to do this with an ArgumentCaptor as shown below, but this 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 dataBaseSelect.selectDataFromDB is called, it will be the layout, and then it returns the result from MapSelect.selectDataFromMap and the argument is passed from dataBaseSelect.selectDataFromDB

+4
source share
3 answers

If you need to replace your own method implementation, you can do something like this:

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

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

, ( ), :

// 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());

, "someMethod" ""

+2

ArgumentCaptor stubbing - Mockito javadoc. Mockito: thenAnswer Vs thenReturn - thenReturn .

thenAnswer - , .

public class SampleTest {
class DataBaseSelect {
    List<Long> selectDataFromDB(Long key){
        throw new UnsupportedOperationException("I dont want to call this");
    }
}

class MapSelect {
    private final Map<Long,List<Long>> mockMap = new HashMap<Long,List<Long>>(){{
        put(1L,Arrays.asList(-1L,1L));
        put(2L,Arrays.asList(-2L,2L));
    }};
    List<Long> selectDataFromMap(Long key){
        return mockMap.get(key);
    }
}

@Test
public void testThenAnswer(){
    DataBaseSelect dataBaseSelect = Mockito.mock(DataBaseSelect.class);
    MapSelect mapSelect = new MapSelect();

    Mockito.when(dataBaseSelect.selectDataFromDB(Mockito.anyLong()))
            .thenAnswer(invocation ->
                    mapSelect.selectDataFromMap((Long)invocation.getArguments()[0])
            );

    TestCase.assertTrue(
            Arrays.asList(-1L,1L).equals(dataBaseSelect.selectDataFromDB(1L))
    );
    TestCase.assertTrue(
            Arrays.asList(-2L,2L).equals(dataBaseSelect.selectDataFromDB(2L))
    );
}
}

Java-7 lambda Answer.

Mockito.when(dataBaseSelect.selectDataFromDB(Mockito.anyLong()))
            .thenAnswer(new Answer<List<Long>>() {
                            @Override
                            public List<Long> answer(InvocationOnMock invocation) throws Throwable {
                                return mapSelect.selectDataFromMap((Long) invocation.getArguments()[0]);
                            }
                        }
            );
+1
  • dataBaseSelect @Mock
  • MockitoAnnotations.initMocks();

, , . , : ....

@Mock
DataBaseSelect dataBaseSelect;

@Before
public void before(){
    MockitoAnnotations.initMocks(this);
}
@Test
public void test() {
     ArgumentCaptor<Long> argumentCaptor = ArgumentCaptor.forClass(Long.class);

     //Maybe you can use when statement Matchers.anyLong()
     //Mockito.when(dataBaseSelect.selectDataFromDB(Matchers.anyLong())).thenReturn(MapSelect.selectDataFromMap(argumentCaptor.getValue()));
     Mockito.when(dataBaseSelect.selectDataFromDB(argumentCaptor.capture())).thenReturn(MapSelect.selectDataFromMap(argumentCaptor.getValue()));

     List<Long> result = dataBaseSelect.selectDataFromDB(argumentCaptor.capture());

     Assert.assertTrue(/*Assert statement*/);
}
-1

Source: https://habr.com/ru/post/1690001/


All Articles