Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Mockito模拟方法行为时按任意顺序匹配列表_Java_Unit Testing_Mockito - Fatal编程技术网

Java 使用Mockito模拟方法行为时按任意顺序匹配列表

Java 使用Mockito模拟方法行为时按任意顺序匹配列表,java,unit-testing,mockito,Java,Unit Testing,Mockito,我有一个使用Mockito的测试,它有一个非常奇怪的行为:它在调试中工作,但在正常运行时失败。经过一些调查,我意识到这是因为我在模仿方法行为,传递一个要匹配的元素列表。但是由于某些原因,列表中的顺序并不总是相同的,因此它不匹配,并且我希望我的mock返回的结果也没有返回,因为这两个列表不是“相等”的 在我的例子中,匹配元素的顺序并不重要。那么,在配置mock时,我如何指定它呢 其实很简单。我们需要一个定制匹配器: import org.apache.commons.collections.Col

我有一个使用Mockito的测试,它有一个非常奇怪的行为:它在调试中工作,但在正常运行时失败。经过一些调查,我意识到这是因为我在模仿方法行为,传递一个要匹配的元素列表。但是由于某些原因,列表中的顺序并不总是相同的,因此它不匹配,并且我希望我的mock返回的结果也没有返回,因为这两个列表不是“相等”的


在我的例子中,匹配元素的顺序并不重要。那么,在配置mock时,我如何指定它呢

其实很简单。我们需要一个定制匹配器:

import org.apache.commons.collections.CollectionUtils;
import org.mockito.ArgumentMatcher;
import java.util.List;
import static org.mockito.Matchers.argThat;

public class InAnyOrderListMatcher extends ArgumentMatcher<List> {

private final List expected;

public InAnyOrderListMatcher(List expected){
    this.expected=expected;
}

@Override
public boolean matches(Object actual) {

    if(actual instanceof List){

        List actualList=(List)actual;

        return CollectionUtils.isEqualCollection(expected,actualList);

    }

    return false;
}

public static List inAnyOrderListMatcherEq(List expected) {
    return argThat(new InAnyOrderListMatcher(expected));
}

}

这是一条单行线。使用Hamcrest
containsInAnyOrder
matcher

when(myMock.myMethod(argThat(containsInAnyOrder(IN_PROGRESS, ABANDONED, EXPIRED))))
    .thenReturn(myValue);

为Mockito和Java8的更新版本添加答案

when(
   mock.method(argThat(t -> t.containsAll(Arrays.asList(IN_PROGRESS, ABANDONED, EXPIRED))))
).thenReturn(myValue);

如果顺序无关紧要,请将StatusCalculator服务更改为接受集合而不是集合。那么无论顺序如何,equals都将返回true


修复API比在单元测试中绕过它要好。

不要重新发明轮子。汉克雷斯特已经有了一个匹配者。看我的答案。是的,你是对的。。但需要注意的是,在大多数情况下,通过该方法将argThat的输出转换为预期类型似乎是强制性的。如果我没有Hamcrest,只有mockito?我不认为这是最佳解决方案,但我通过给出多个when语句绕过了这个问题。如果您只是想通过测试,那么这可能是最简单的方法(如果您的收藏中有少量项目)!
when(myMock.myMethod(argThat(containsInAnyOrder(IN_PROGRESS, ABANDONED, EXPIRED))))
    .thenReturn(myValue);
when(
   mock.method(argThat(t -> t.containsAll(Arrays.asList(IN_PROGRESS, ABANDONED, EXPIRED))))
).thenReturn(myValue);