Mockito为不同的参数值返回相同的结果

时间:2015-10-22 23:22:44

标签: java mockito junit4

我对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无法读取源代码,因此它依赖于代码的静态状态,记录每次调用时应返回的内容。但是这种行为完全使我感到困惑,因为当它为一组未编程的参数发送null或空对象时,它返回不同参数的相同对象。 我使用Java 1.7.0_79和Mockito 1.10.19和Junit 4.11。 我错过了一些重要的事情,或者有人可以解释这种行为吗?

2 个答案:

答案 0 :(得分:3)

您只是存根以下调用

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。   通常它只返回一些空值。

     

答案可用于定义未锁定的返回值   调用

     

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

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

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

答案 1 :(得分: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