mockito 模拟包含函数和对象作为参数的方法?

31moq8wy  于 2023-10-18  发布在  其他
关注(0)|答案(1)|浏览(126)

在写Junit单元测试用例时,我试图使用Mockito来模拟方法callservice。

public CompletableFuture<String> getInfo(String something) 
{

CompletableFuture<String> future = new CompletableFuture<>();
JAXBElement<Class1> request = SoapRequests
        .buildRequest(str1, str2);
        
Consumer<Exception> exception = ex->{
future.complete("exception");  
}

Consumer<FaultType> fault = fault->{
future.complete("exception",FaultType.class);  
}

String target="target";

JAXBElement<?> element = soapConnector.callservice(
        target, request,
        fault, ex, false);

}

我尝试了以下方法。但是,它总是返回空元素

JAXBElement<?> response = jaxbUnmarshaller.unmarshal("xmlString",
          SomeClass12.class);

JAXBElement<SomeClass> request = SoapRequests
          .buildRequest("", "", "");
JAXBElement<SomeClass> requestSpy = spy(request);         

Consumer<FaultType> faultType = mock(Consumer.class);
Consumer<Exception> exception = mock(Consumer.class);

 lenient().when(soapConnector.callservice(
          "target", requestSpy,
          faultType, exception, false)).thenAnswer(i->response);
jrcvhitl

jrcvhitl1#

如果你想模拟一个带参数的方法,mockito使用equal方法来比较参数。如果它们等于调用mock时使用的参数,则mock返回该值。如果没有找到匹配项,mock将返回null。在您的例子中,相等性检查永远不会返回true,因为一些参数是您的测试用例的本地参数,因此mock返回null。
举例来更好地解释这一点:
假设以下类:

class Dummy {
        public String doSomething(String argument) {
            return "";
        }
}

在我们的测试中,我们这样做:

@Test
public void test() {
    Dummy dummy = mock(Dummy.class);

    when(dummy.doSomething("foo")).thenReturn("bar");

    System.out.println(dummy.doSomething("foo")); // Will print bar
    System.out.println(dummy.doSomething("something else")); // will print null
}

正如我们所看到的,只有当参数匹配时,我们的mock才会返回指定的值。
回到你的例子,特别是requestSpy在实际代码中不等于request,消费者mock也不等于request,因为它们是局部变量,也是mock。
我不太确定你想做什么,但是在模拟一个函数的时候没有必要传递模拟。正确地模拟你的函数的一个可能的方法是:

Mockito<JAXBElement<?>>.when(soapConnector.callservice(
          eq("target"), any(),
          any(), any(), eq(false))).thenReturn(response);

通过这种方式,我们可以确保提供参数target和false,而不关心其他参数。如果你想检查参数,可以使用ArgumentCaptor。
还要注意我是如何显式地为when()函数定义泛型参数以确保类型正确的。
使用的静态导入:

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;

相关问题