我有一些困难嘲弄一些单元测试的必要依赖。我怀疑我没有正确理解如何使用Mockito when().ThenReturn()。
下面是我要测试的服务的代码部分(希望是相关的):
@Singleton
public class AppointmentService {
private DataConnector connector;
@Inject
public AppointmentService(DataConnector connector) {
this.connector = connector;
}
public Appointment getAppointment(UriInfo uriInfo, String id) {
HttpResponse response = connector.getAppointment(id);
return validateResponse(response, uriInfo);
}
protected Appointment validateResponse(HttpResponse response, UriInfo uriInfo) {
try {
AppointmentWrapper appointmentWrapper = JacksonJsonUtility.readValue(response.getInputStream(), AppointmentWrapper.class);
if(appointmentWrapper.getAppointment()!=null) {
return appointmentConverterHelper(appointmentWrapper.getAppointment(), uriInfo.getPath());
}
} catch(IOException e) {
throw new ResponseParsingException("IOException: " + e.getMessage());
}
}
protected Appointment appointmentConverterHelper(ExternalAppointmentModel appointmentDto, String uriPath) {
if (appointmentDto == null) {
throw new BrickworkQueryException("Got an invalid appointment object from Brickwork!");
}
Customer customer = new Customer(new Name(appointmentDto.getCustomer().getName()),
appointmentDto.getCustomer().getEmail(),
String.valueOf(appointmentDto.getCustomer().getCode()));
return new Appointment(
appointmentDto.getId(),
customer);
}
}
我的理解是,这个方法的单元测试应该如下所示:
public class AppointmentServiceTest {
private UriInfo mockUriInfo;
private HttpResponse mockHttpResponse;
@Mock
private DataConnector mockDataConnector;
@InjectMocks
private AppointmentService appointmentService;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mockUriInfo();
mockHttpResponse();
}
private void mockUriInfo() {
mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getRequestUri()).thenReturn(
URI.create("http://localhost:8080"));
}
private void mockHttpResponse() {
mockHttpResponse = mock(HttpResponse.class);
when(mockHttpResponse.getInputStream()).thenReturn(
IOUtils.toInputStream("{\"appointment\":{}}"));
}
@Test
public void testGetAppointment() throws Exception {
when(mockDataConnector.getAppointmentById(Mockito.anyString())).
thenReturn(mockHttpResponse);
when(appointmentService.validateResponse(Mockito.any(HttpResponse.class), Mockito.any(UriInfo.class))).
thenReturn(new Appointment());
appointmentService.getAppointment(mockUriInfo, "12345");
verify(mockDataConnector).getAppointment(Mockito.anyString());
}
}
当我运行测试时,在尝试调用appointmentTo.getCustomer()时,在appointmentConverterHelper方法中得到一个NullPointerException(可以理解为空)。由于代码现在正在运行,在我看来,我将需要在我的mockHttpResponse中返回一个包含完全有效约会的InputStream。既然我有when(appointmentService.validateresponse(mockHttpResponse,mockUriInfo)).thenreturn(new Appointment());
难道不应该调用validateresponse
并返回空的Appointment对象而不是实际运行validateresponse吗?
这里是AppointmentServiceTest的exception-line 140的堆栈跟踪是上面的when
语句,以供参考。AppointmentsService的第176行是JacksonJsonUtility.ReadValue(response.GetInputStream(),appointmentWrapper.Class);
行:ValidateResponse
方法开头的
java.lang.NullPointerException
at com.nike.appointmentservice.service.AppointmentsService.validatedResponse(AppointmentsService.java:176)
at com.nike.appointmentservice.service.AppointmentsServiceTest.testGetAppointmentById(AppointmentsServiceTest.java:140)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:119)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)```
基于这篇文章,我认为监视AppointmentService是允许我模拟validateresponse
调用的方法。下面是我的测试现在的样子:
public class AppointmentServiceTest {
private UriInfo mockUriInfo;
private HttpResponse mockHttpResponse;
@Mock
private DataConnector mockDataConnector;
@Spy
private AppointmentsService appointmentsServiceSpy;
@InjectMocks
private AppointmentService appointmentService;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
appointmentsServiceSpy = spy(appointmentsService);
mockUriInfo();
mockHttpResponse();
}
private void mockUriInfo() {
mockUriInfo = mock(UriInfo.class);
when(mockUriInfo.getRequestUri()).thenReturn(
URI.create("http://localhost:8080"));
}
private void mockHttpResponse() {
mockHttpResponse = mock(HttpResponse.class);
when(mockHttpResponse.getInputStream()).thenReturn(
IOUtils.toInputStream("{\"appointment\":{}}"));
}
@Test
public void testGetAppointment() throws Exception {
when(mockDataConnector.getAppointmentById(Mockito.anyString())).
thenReturn(mockHttpResponse);
doReturn(new Appointment()).when(appointmentsServiceSpy).validateResponse(Mockito.any(HttpResponse.class), Mockito.any(UriInfo.class));
appointmentServiceSpy.getAppointment(mockUriInfo, "12345");
verify(mockDataConnector).getAppointmentById(Mockito.anyString());
}
}
我仍然在实际的appointmentServicespy.getappointment
调用中遇到一个异常,但我认为这是一个与如何使用间谍有关的单独问题。就原问题而言,使用带有doReturn().when()
语句的spy可以解决使用when().thenReturn()
语句时错误调用方法的问题。
我认为问题可能是when
语句试图与特定实例匹配,但失败了。要开始使用Mockito单元测试,您应该将when
语句中的特定值替换为表示“anything”的Mockito占位符。例如:
when(mockDataConnector.getAppointmentById(Mockito.anyString())).
thenReturn(mockHttpResponse);
when(appointmentService.validateResponse(Mockito.any(HttpResponse.class), Mockito.any(UriInfo.class))).
thenReturn(new Appointment());
当基本单元测试工作时,就可以添加更具体的单元测试。
更新
我现在注意到,您正在尝试测试appointmentService
类,但同时也在模拟该类中的validateresponse
html" target="_blank">方法。作为一个Mockito专家,我还不足以知道这是否完全不正确,但这不是我在单元测试中使用Mockito的方式。我正在测试的类根本没有被嘲弄,而是模拟它调用的类,以便模拟变量行为,并查看被测试类如何响应。
我认为您可能需要模拟JacksonJsonUtility
类(powermock帮助处理静态类),并删除ValidateResponse
方法上的模拟。您将需要构造JacksonJsonUtility.ReadValue
方法的模拟响应,以便它包含AppointmentService类所需的所有内容。
我使用下面的命令进行了mockito-junit测试。变量serviceTask是接口的实例,称为serviceTask。我在申报中使用了@Mock 声明: 命令行: 堆栈跟踪: Java语言lang.NullPointerException在sun。反映NativeMethodAccessorImpl。sun上的invoke0(本机方法)。反映NativeMethodAccessorImpl。在
我试图存根这个方法:QueryUtils.to顺序(排序,根,构建器)和我正在做 但它进入queryUtils方法体,它会说Sort为null,并抛出一个NPE。但是,当它是存根时,为什么需要进入方法体?我以前没有遇到过这个问题,我认为它不应该关心该方法的内部逻辑是什么。
有一个类,并希望模拟/存根一个方法 测试; 在< code > when(the spy . merge list(any(list . class),any(HttpCookie.class))上出现异常< code > NullPointerException 。then return(fakeCookieList);。 日志显示两行: 显然,mergeList()是用空参数执行的,并在(Ht
我在测试中使用@MockBean时使用Mockito.when(). thenBack()遇到了一些问题。 这是我的测试课: 其中getPayload()返回将使用Jackson转换为控制器对象的有效负载字符串。 这是我正在测试的控制器: 我现在收到Mockito的投诉。什么时候然后返回用法: 最后这里是我的KafkaPublisher: 我有两个问题: 如果我取出Mockito.when.the
我有一个GWT应用程序,我从文本框中获取输入,检查正则表达式的值,如果匹配,然后我将该文本添加到表格中。当我为例如“你好”输入任何正确的输入时,它工作得非常好。 任何帮助都将不胜感激。
问题内容: 如果返回错误,是否仍在调用? 问题答案: 不,延迟功能不会运行。 这是log.Fatal的描述: 致命等同于Print(),然后调用os.Exit(1)。 呼叫,其描述在这里: 退出使当前程序以给定的状态码退出。按照惯例,代码零表示成功,代码零表示错误。程序立即终止;延迟功能未运行。 示范 如果您确实需要在程序完成之前正确关闭资源或执行某些任务,请不要使用。