【问题标题】:Mockito returns the same result for different parameter valuesMockito 对不同的参数值返回相同的结果
【发布时间】:2015-10-22 23:22:44
【问题描述】:

我在使用 Mockito 时遇到了这种奇怪的行为,但我不确定这是否是预期的行为 :-(。以下代码是我想出的一个虚构的 Java 代码来强调这一点。

import org.junit.Test;
import org.mockito.Mockito;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.when;

public class StringServiceTest {

    enum Style {
        NONE, ITALIC, BOLD
    }

    private class StringService {

        public List<String> getString(Set<String> words, long fontSize, Style fontStyle) {
            return new ArrayList<>();
        }
    }

    @Test
    public void testGetString() {

        StringService stringService = Mockito.mock(StringService.class);

        Set<String> words = new HashSet<>();
        List<String> sentence = new ArrayList<>();

        when(stringService.getString(words, 12L, Style.BOLD)).thenReturn(sentence);

        List<String> result = stringService.getString(words, 234L, Style.ITALIC);
        List<String> result1 = stringService.getString(words, 565L, Style.ITALIC);
        List<String> result2 = stringService.getString(words, 4545L, Style.NONE);

        assertThat("Sentences are different", result.hashCode() == result1.hashCode());
        assertThat("Sentences are different", result.hashCode() == result2.hashCode());
    }
}

由于 Mockito 无法读取源代码,它依赖于代码的静态状态来记录每次调用应返回的内容。但是这种行为完全让我感到困惑,因为当它应该为一组它没有编程的参数发送空或空对象时,它会为不同的参数返回相同的对象。 我将 Java 1.7.0_79 和 Mockito 1.10.19 与 Junit 4.11 一起使用。 我是否遗漏了一些重要的东西,或者有人可以解释一下这种行为吗?

【问题讨论】:

    标签: java mockito junit4


    【解决方案1】:

    您仅存根了以下调用

    when(stringService.getString(words, 12L, Style.BOLD)).thenReturn(sentence);
    

    与您的任何调用都不匹配

    List<String> result = stringService.getString(words, 234L, Style.ITALIC);
    List<String> result1 = stringService.getString(words, 565L, Style.ITALIC);
    List<String> result2 = stringService.getString(words, 4545L, Style.NONE);
    

    对于未存根的方法,Mockito 使用RETURN_DEFAULTS

    如果模拟没有存根,则每个模拟的默认Answer。 通常它只是返回一些空值。

    Answer 可用于定义 unstubbed 的返回值 调用。

    此实现首先尝试全局配置。如果有 没有全局配置然后它使用ReturnsEmptyValues(返回 零、空集合、空值等)

    换句话说,您对getString 的每一次调用实际上都返回了一些空的List(Mockito 的当前实现返回一个新的LinkedList 实例)。

    由于所有这些List 实例都是空的,它们都具有相同的hashCode

    【讨论】:

      【解决方案2】:

      由于您正在模拟该类,因此它返回的是一般返回值。它不会返回您认为的内容。在这种情况下,它是LinkedList。列表hashCode 取决于内容:

      /**
       * Returns the hash code value for this list.
       *
       * <p>This implementation uses exactly the code that is used to define the
       * list hash function in the documentation for the {@link List#hashCode}
       * method.
       *
       * @return the hash code value for this list
       */
      public int hashCode() {
          int hashCode = 1;
          for (E e : this)
              hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
          return hashCode;
      }
      

      如果你打印出hashCode,你会发现它是1

      【讨论】:

      • 您提出了一个很好的观点,即 new ArrayList().hashCode() 返回 1. +1。您的观点与 Sotirios 的回答一起解释了我所追求的。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-28
      相关资源
      最近更新 更多