当前位置: 首页 > 知识库问答 >
问题:

java中如何用新函数替换模拟函数

巴英韶
2023-03-14

我用Mockito写UT,我想替换我的mock函数(哪个DB选择操作)

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

使用我在测试类中编写的新函数(使用map模拟数据库选择);

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

我想用正确的键输入返回正确的值

我试图这样做使用ArgumentCaptor如下,但它没有工作,因为我想

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

我想当调用dataBaseSelect.selectDataFromDB时,它将被模拟,然后从MapSelect.selectDataFromMap返回结果,参数从DataBaseSelect.selectDataFromDB传递

共有3个答案

空佐
2023-03-14
  • 您是否将dataBaseSelect对象注释为@Mock
  • 你做注释吗。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*/);
}
东方化
2023-03-14

不要将ArgumentCaptor用于存根-Mockito javadoc中有警告。还要阅读这个Mockito:thenAnswer Vs thenReturn-thenReturn用于模拟常量结果,不能以动态方式工作。

那么答案就是你想要的。

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

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]);
                            }
                        }
            );
松建本
2023-03-14

如果您需要替换您自己的方法实现,您可以这样做:

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

在这个例子中,期望调用一次“某物方法”并返回人“约翰”

 类似资料:
  • null 我读过PDO的书。如何使用MySQL或MSSQL将代码更新为PDO?

  • 我有一个jUnit测试,测试我的一个函数。在这个函数中,我调用了另一个类的方法,我想用mockito模拟这个方法。然而,我似乎不能实际嘲笑这一点。下面是我的jUnit测试的样子: 编辑:在我的MainClassImTesting()中。我正在调用的test()函数,它调用authenticateUser()并向它传递一个hashMap。

  • 问题内容: 我正在尝试第一次使用PowerMockito模拟类构造函数,但是它不起作用。我当前的代码是: 测试失败,因为返回的值为“ Fail”。我的问题在哪里? 问题答案: Okey,找到答案了,您需要致电 代替

  • 我正在尝试模拟静态函数(getBatchId()和sendPost())以获得以下代码: 上述方法的单元测试用例代码:

  • 问题内容: Java是否具有Oracle功能的类似物? 问题答案: 您可以使用: 编辑: 根据此文档 MONTHS_BETWEEN返回小数结果,我认为此方法可以执行相同的操作:

  • 我有下面的打字稿类,我想测试在笑话。 这是我的测试: 如何模拟MyClass中使用的foo函数,以使测试通过?