Java 使用any()或anyList()时,使用ArrayList/List参数的stubout方法失败

Java 使用any()或anyList()时,使用ArrayList/List参数的stubout方法失败,java,testing,mockito,spy,Java,Testing,Mockito,Spy,我有一个java类 class Blah{ public Blah(){ } public String testMe(List<String> s){ return new String("hello "+s.get(0)); } public String testMeString(String s){ return new String("hel

我有一个java类

class Blah{
        public Blah(){

        }
        public String testMe(List<String> s){
            return new String("hello "+s.get(0));
        }


        public String testMeString(String s){
            return new String("hello "+s);
        }


    }

测试通过any()和any(String.class)。

您的NullPointerException是在存根期间而不是在测试期间抛出的

这是因为
Matchers.any()
实际上返回
null
,因此如果在调用实方法时使用它,则将
null
作为参数传递
testMeString
之所以正常工作,是因为
null+s
不会导致NullPointerException(而是使用字符串
“null”

而不是:

when(blah.testMe(any())).thenReturn("intercepted");
你需要使用

doReturn("intercepted").when(blah).testMe(any());

这被记录在Mockito文档中(虽然不太清楚)。

通过此语句
blah.testMe()
包含在
when()
中,它调用了真正的方法:

when(blah.testMe(Matchers.any())).thenReturn("intercepted");
为了避免这种情况,应该使用
doReturn(…).when(…).methodToInvoke()
模式

doReturn("intercepted").when(blah).testMe(Matchers.any()));
您注意到,使用这种语法,
blah.testMe()
语句没有指定任何地方。所以这不是所谓的

除此之外,我认为您不需要任何间谍来测试此方法。
间谍是模拟中一种非常特殊的工具,只有在没有任何选择的情况下才能使用:你需要模拟被测对象,这是一种不好的做法,你不能重构实际的代码

但在这里你可以做:

@Test
public void testTestMe(){
    Blah blah = new Blah();
    ArrayList<String> l = new ArrayList<String>();
    l.add("oopsie");
    assertEquals("hello oopsie",blah.testMe(l));
 }
@测试
公共void testme(){
废话废话=新废话();
ArrayList l=新的ArrayList();
l、 添加(“oopsie”);
assertEquals(“你好,oopsie”,blah.testMe(l));
}

您应该重新考虑使用
spy
mock
等。当您有外部系统、rest web服务、单元测试期间不想调用的DB时,应该使用这些工具。在像这样的简单场景中,只需创建一些测试输入并检查输出

@Test public void testTestMeString(){
 //given
  List<String> list = Arrays.asList("aaa");
 //when
 String result = blah.testMe(list);
 //then
 assertEquals(result, "hello aaa");
 }
@Test public void testmestring(){
//给定
List=Arrays.asList(“aaa”);
//什么时候
字符串结果=blah.testMe(列表);
//然后
assertEquals(结果“你好,aaa”);
}

当您对给定的
感兴趣时,当,然后
检查BDD。

等待,您的系统正在测试哪种方法?如果您正在测试
testMe
,那么为什么要尝试监视
testMe
?好问题,我正在尝试了解监视+何时+返回是如何工作的。让我澄清我的问题谢谢大家的回答。丹尼尔是第一个,所以我会将他标记为正确答案,尽管所有的答案似乎都是相似的。
@Test
public void testTestMe(){
    Blah blah = new Blah();
    ArrayList<String> l = new ArrayList<String>();
    l.add("oopsie");
    assertEquals("hello oopsie",blah.testMe(l));
 }
@Test public void testTestMeString(){
 //given
  List<String> list = Arrays.asList("aaa");
 //when
 String result = blah.testMe(list);
 //then
 assertEquals(result, "hello aaa");
 }