Mock根据参数返回一个列表

时间:2017-08-30 03:39:06

标签: java mocking mockito

我尝试使用List of String模拟请求,并使用传递的参数创建对象列表...类似于:

        when(tagDao.findByNameInOrderByName(Matchers.anyListOf(String.class))).thenReturn(new Answer<List<Tag>>() {
        @Override
        public List<Tag> answer(InvocationOnMock invocation) throws Throwable {
            // Object[] args = invocation.getArguments();
            List<Tag> tags = new ArrayList<Tag>();
            return tags;
        }
    });

我尝试过像

这样的事情
font-feature-settings: 'liga' 1;

我收到以下错误: 方法thenReturn(List)在类型OngoingStubbing&gt;中不适用于参数(新答案&gt;(){})

2 个答案:

答案 0 :(得分:3)

我认为您应该使用thenAnswer代替thenReturn

when(tagDao.findByNameInOrderByName(Matchers.anyListOf(String.class))).thenAnswer(new Answer<List<Tag>>() {
            @Override
            public List<Tag> answer(InvocationOnMock invocationOnMock) throws Throwable {
                Object[] args = invocationOnMock.getArguments();
                List<Tag> tags = new ArrayList<Tag>();
                return tags;
            }
        });

答案 1 :(得分:1)

我认为您正在寻找技术解决方案......以解决应以不同方式解决的问题。

您拥有的内容:某些方法由您的测试代码调用,传递值列表。现在你想以某种方式返回结果构建&#34;围绕&#34;那些传入的价值。另一个答案告诉你如何到达那里(我会看看你是否可以使用ArgumentCaptor来做到这一点)。

但让我们退后一步。请记住,您编写单元测试来测试某种方法的公共合同的一个特定方面。但似乎findByNameInOrderByName()会有不同的调用。现在,您正在寻找一种为不同输入生成不同返回结果的方法。

我的建议不是这样做。相反:明确地将事物分成不同的测试用例。喜欢在:

@Test
public void testXyzWithFooBar() {
  when(tagDao.findByNameInOrderByName(Arrays.asList("foo", "bar").thenReturn(Arrays.asList(x, y));
  ... call xyz ...

@Test
public void testXyzWithFooOnly() {
  when(tagDao.findByNameInOrderByName(Arrays.asList("foo").thenReturn(Arrays.asList(z, b));
  ... call xyz ...

换句话说:我宁愿努力避免让模拟对象根据输入参数隐式返回 的额外复杂性。

相反:清楚地表达预期的案例明确。这也会导致更严格的测试。你的想法意味着:任何都可以进入那个模拟的方法调用。我的版本明确地陈述了您期望发生的事情。