当前位置: 首页 > 知识库问答 >
问题:

当使用when/thenReturn设置模拟存根时,出现异常

戈正初
2023-03-14

有一个类,并希望模拟/存根一个方法

public class ToBeMocked {
    public List<HttpCookie> mergeList(@NonNull List<HttpCookie> cookies, HttpCookie oneCookie) {
        
        System.out.println("+++ mergeList(), cookies:"+cookies+", oneCookie:"+oneCookie);

        HashMap<String, HttpCookie> map = new HashMap();
        if (oneCookie != null) {
            map.put("A", oneCookie);
        }
        for (HttpCookie cookie : cookies) {  //<=== it crashed at this line
            map.put(cookie.getName(), cookie);
        }

        List<HttpCookie> list = new ArrayList<HttpCookie>();
        for (Map.Entry<String, HttpCookie> entry : map.entrySet()) {
           list.add(entry.getValue());
        }
        return list;
    }
}

测试;

@Test
public void test() {

        List<HttpCookie> aCookieList = new ArrayList<>();
        HttpCookie a1Cookie = new HttpCookie("A1", "a1");
        HttpCookie a2Cookie = new HttpCookie("A2", "a2");
        aCookieList.add(a1Cookie);
        aCookieList.add(a2Cookie); 
        
        HttpCookie bCookie = new HttpCookie("B", "b1");

        List<HttpCookie> fakeCookieList = new ArrayList<>();
        fakeCookieList.add(bCookie);
        fakeCookieList.addAll(aCookieList);

    ToBeMocked theSpy = spy(new ToBeMocked());

    System.out.println("+++ 111 test(), aCookieList:"+aCookieList+", bCookie:"+bCookie);
        
    //when(theSpy.mergeList(any(List.class), any(HttpCookie.class)))
    when(theSpy.mergeList(eq(aCookieList), any(HttpCookie.class))). //<== exception on this
           .thenReturn(fakeCookieList);

    System.out.println("+++ 222 test()");
    // test
    // it would call some other function which internally call the mergeList(aCookieList, bCookie), and expect to generate a list from the stubbed result to use, here just make it simple to be run able to show the problem
    List<HttpCookie> list = theSpy.mergeList(aCookieList, bCookie);
        
    // verify
    assertEquals(list.contains(bCookie), true);        
}

在< code > when(the spy . merge list(any(list . class),any(HttpCookie.class))上出现异常< code > NullPointerException 。then return(fakeCookieList);。

日志显示两行:

Called loadFromPath(/system/framework/framework-res.apk, true); mode=binary sdk=28
+++ 111 test(), aCookieList:[A1="a1", A2="a2"], bCookie:B="b1"
+++ mergeList(), cookies:null, oneCookie:null

java.lang.NullPointerException

显然,mergeList()是用空参数执行的,并在(HttpCookie cookie:cookie)的<code>处崩溃。

问题:

我认为time(). thenBack()只是为了设置存根,也就是说当使用任何参数(或特定参数)调用mock的mergeList()时,它应该返回提供的列表。

time(). thenBack()没有正确的参数吗?为什么它似乎在time(). thenBack()中执行mergeList()?

共有2个答案

谷德本
2023-03-14

@George利沃夫的解决方案有效。

这里解释了doReturn(…)和theReturn(……)之间的区别,特别是在spy中,Doreturnn(…)不会进行真正的方法调用。但还没有找到记录行为差异的地方。

如果使用spied对象(用@Spy注释)而不是mock对象(用@Mock注释),这两种方法的行为会有所不同:when(...)然后返回(...)在返回指定值之前进行真正的方法调用。因此,如果被调用的方法抛出一个异常,你必须处理它/模拟它等等。当然,您仍然会得到您的结果(您在Return(...))多雷托(...)什么时候(...)根本不调用方法。

弘承运
2023-03-14

来自Mockito doc:

有时,使用when(Object)来截留间谍是不可能或不切实际的。因此,在使用SPIE时,请考虑用于存根的doReturn |Answer| Throw()方法家族。

所以试试看:

  doReturn(fakeCookieList).when(theSpy)
            .mergeList(eq(aCookieList), any(HttpCookie.class));

但一般来说,不太清楚使用这种测试测试什么。测试中的方法是<code>mergeList,同时通过调用<code>doReturn

 类似资料:
  • 我使用下面的命令进行了mockito-junit测试。变量serviceTask是接口的实例,称为serviceTask。我在申报中使用了@Mock 声明: 命令行: 堆栈跟踪: Java语言lang.NullPointerException在sun。反映NativeMethodAccessorImpl。sun上的invoke0(本机方法)。反映NativeMethodAccessorImpl。在

  • 我试图存根这个方法:QueryUtils.to顺序(排序,根,构建器)和我正在做 但它进入queryUtils方法体,它会说Sort为null,并抛出一个NPE。但是,当它是存根时,为什么需要进入方法体?我以前没有遇到过这个问题,我认为它不应该关心该方法的内部逻辑是什么。

  • 我试图测试调用接口方法时是否传递了正确的值。我得到以下错误: org.mockito.exceptions.misusing.未完成验证异常:缺少的方法调用验证(mock)在这里:- 正确验证示例:验证(模拟)。doSomething() 此验证行上正在抛出错误:

  • 我有一些困难嘲弄一些单元测试的必要依赖。我怀疑我没有正确理解如何使用Mockito when().ThenReturn()。 下面是我要测试的服务的代码部分(希望是相关的): 我的理解是,这个方法的单元测试应该如下所示: 当我运行测试时,在尝试调用appointmentTo.getCustomer()时,在appointmentConverterHelper方法中得到一个NullPointerEx

  • 当我调用hibernate save时,我会面临这个异常,我不知道如何解决这个问题。在我的例子中,我将join列从PrimaryKey更改为另一列,因此我面临这个异常。我不想保存客户与承销商和我只想保存外键。 我的域模型是:

  • 我在micronaut中有以下接口来执行HTTP POST请求: 我有一个调用接口的类: 我想在我的spock测试中模拟/存根API调用,我尝试了以下方法: 然而,我得到的错误: