首页 > 解决方案 > 以参数作为参数的模拟方法返回失败

问题描述

我没有写测试,因为我的 when().thanReturn() 的答案没有返回任何东西。我无法模拟这种行为(设置是 Spring Boot、Java 8、Junit 4)。问题是被调用的方法将方法引用作为参数:

List<PubSubMessage> findMessages(DateCheckerPredicate whichDateFunction, MessageRepoPredicate whichQueryToUse, int tableId) {
List<PubSubMessage> rulesToPublish = new ArrayList<>();
    List<Object> queryResult = whichQueryToUse.findObjects(tableName);
    if(queryResult != null) {
        queryResult.forEach(object -> {
            if(whichDateFunction.checkDates(object)) {
                rulesToPublish.add(new PubSubMessage(tableId, object.getId()));
            }
        });
    }
    return rulesToPublish;
}

调用该方法看起来像这样:

public void methodToTest {
   List<PubSubMessage> messages = dao.findMessages(MessageDateChecker::msgCanBePublished, msgRepo::findMsgesToPublish, tableId);
}

其中MessageDateChecker使用静态“辅助方法”,msgRepo是一个使用 Springs @Service注释并使用jdbcTemplates查询数据库的类。这个类看起来像这样:

private Dao dao;
private MsgRepo msgRepo;
@Autowired
public SomeService(Dao dao, MsgRepo msgRepo) {
   this.dao = dao;
   this.msgRepo = msgRepo;
}

测试设置如下所示:

@Mock
private Dao dao;
@Mock
private MsgRepo msgRepo;
@InjectMock
public SomeService(dao, msgRepo)
private int tableId = 1;
private String tableName = "someTableName";


@Test
public void someTest() {
    List<PubSubMessage> list = new ArrayList<>();
    list.add(new PubSubMessage(tableId, 12));
    List<Object> objects = new ArrayList<>();
    objects.add(new Object(12, new Date(), null));
    when(dao.findMessages(MessageDateChecker::msgCanBePublished, msgRepo::findMessagesToActivate, tableId)).thenReturn(list);

   someService.methodToTest() //in here findRules is getting called()

   verify(someClass,times(1)).someMethod()
}

就像我上面提到的when().thanReturn()应该返回预定义的列表,但是在运行测试时,它总是返回null。有没有人可以提供一些帮助?可能我需要更好地模拟在参数处传递的方法引用。但到目前为止,我没有做对。

标签: springjava-8functional-programmingmockitomethod-reference

解决方案


正如我在评论中所写,只需any()使用

when(dao.findMessages(any(), any(), eq(tableId))).thenReturn(list);

问题是,如果你传递类似的东西SomeClass::someMethod,这会创建一个实现预期功能接口的中间对象。如果您在测试代码中执行相同操作,则会创建另一个对象,因此匹配器不会将它们视为相同。


推荐阅读