【问题标题】:Mock return a list based on parameters模拟根据参数返回一个列表
【发布时间】:2017-08-30 03:39:06
【问题描述】:

我正在尝试使用字符串列表模拟请求并使用传递的参数创建对象列表...类似于:

        when(tagDao.findByNameInOrderByName(Matchers.anyListOf(String.class))).thenReturn(new ArrayList<Tag>() {
        /**
         * 
         */
        private static final long serialVersionUID = 8227782193263533677L;
        {
            add(new Tag("name"));
            add(new Tag("surname"));
        }
    });

我尝试过类似的东西

        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;
        }
    });

我收到以下错误: OngoingStubbing> 类型中的 thenReturn(List) 方法不适用于参数(new Answer>() {})

【问题讨论】:

    标签: java mocking mockito


    【解决方案1】:

    我认为你应该使用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;
                }
            });
    

    【讨论】:

      【解决方案2】:

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

      你有什么:一些方法被你的测试代码调用,传递一个值列表。现在你想以某种方式返回一个“围绕”这些传入值构建的结果。另一个答案告诉你如何到达那里(我本来想看看你是否可以使用 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 ...
      

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

      相反:明确清楚地表达预期的情况。这也导致了更严格的测试。你的想法意味着:anything 可以去那个模拟的方法调用。我的版本清楚地说明了你期望发生的事情。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-07-25
        • 2021-09-23
        • 2017-11-22
        • 2015-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-23
        相关资源
        最近更新 更多