英文:
Why Mockito says that my stubbings are unnecessary
问题
以下是要翻译的代码部分:
StudentServiceTests
package com.mdv.secondservice;
import com.mdv.secondservice.api.dto.ThirdServiceStudentDto;
import com.mdv.secondservice.api.proxy.ThirdServiceProxy;
import com.mdv.secondservice.db.model.Student;
import com.mdv.secondservice.db.repository.StudentRepository;
import com.mdv.secondservice.service.StudentService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.convert.ConversionService;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.when;
@SpringBootTest
@ExtendWith(MockitoExtension.class)
public class StudentServiceTests {
@Mock
private StudentRepository studentRepository;
@Mock
private ConversionService conversionService;
@Mock
private ThirdServiceProxy thirdServiceProxy;
@InjectMocks
private StudentService studentService;
private Student student;
private ThirdServiceStudentDto thirdServiceStudentDto;
@BeforeEach
void init() {
final String middleName = "middleName";
final String lastName = "lastName";
student = Student.builder()
.middleName(middleName)
.lastName(lastName)
.build();
thirdServiceStudentDto = new ThirdServiceStudentDto(lastName);
}
@Test
void createStudent_StudentWasCreated() {
when(conversionService.convert(any(Student.class), same(ThirdServiceStudentDto.class)))
.thenReturn(thirdServiceStudentDto);
when(thirdServiceProxy.createStudent(any(ThirdServiceStudentDto.class))).thenReturn(student);
when(studentService.createStudent(student)).thenReturn(student);
Student returnedStudent = studentService.createStudent(student);
assertThat(returnedStudent).isEqualTo(student);
}
}
StudentService
package com.mdv.secondservice.service;
import com.mdv.secondservice.api.dto.ThirdServiceStudentDto;
import com.mdv.secondservice.api.proxy.ThirdServiceProxy;
import com.mdv.secondservice.db.model.Student;
import com.mdv.secondservice.db.repository.StudentRepository;
import feign.FeignException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.ConversionService;
import org.springframework.stereotype.Service;
@Service
@Slf4j
@RequiredArgsConstructor
public class StudentService {
private final StudentRepository studentRepository;
private final ConversionService conversionService;
private final ThirdServiceProxy thirdServiceProxy;
public Student createStudent(Student student) throws FeignException.InternalServerError {
ThirdServiceStudentDto thirdServiceStudentDto =
conversionService.convert(student, ThirdServiceStudentDto.class);
Student createdStudent = thirdServiceProxy.createStudent(thirdServiceStudentDto);
createdStudent.setMiddleName(student.getMiddleName());
studentRepository.save(createdStudent);
return createdStudent;
}
}
请注意,这是您提供的代码的翻译版本,没有其他内容。如果您需要更多帮助或有其他问题,请随时告诉我。
英文:
I'm trying to mock Spring's ConversionService so convert() method always returns the dto created by me, but Mockito says that my stubbings are unnecessary and mocked ConversionService returns null.
Here's the code:
StudentServiceTests
package com.mdv.secondservice;
import com.mdv.secondservice.api.dto.ThirdServiceStudentDto;
import com.mdv.secondservice.api.proxy.ThirdServiceProxy;
import com.mdv.secondservice.db.model.Student;
import com.mdv.secondservice.db.repository.StudentRepository;
import com.mdv.secondservice.service.StudentService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.convert.ConversionService;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.when;
@SpringBootTest
@ExtendWith(MockitoExtension.class)
public class StudentServiceTests {
@Mock
private StudentRepository studentRepository;
@Mock
private ConversionService conversionService;
@Mock
private ThirdServiceProxy thirdServiceProxy;
@InjectMocks
private StudentService studentService;
private Student student;
private ThirdServiceStudentDto thirdServiceStudentDto;
@BeforeEach
void init() {
final String middleName = "middleName";
final String lastName = "lastName";
student = Student.builder()
.middleName(middleName)
.lastName(lastName)
.build();
thirdServiceStudentDto = new ThirdServiceStudentDto(lastName);
}
@Test
void createStudent_StudentWasCreated() {
when(conversionService.convert(any(Student.class), same(ThirdServiceStudentDto.class)))
.thenReturn(thirdServiceStudentDto);
when(thirdServiceProxy.createStudent(any(ThirdServiceStudentDto.class))).thenReturn(student);
when(studentService.createStudent(student)).thenReturn(student);
Student returnedStudent = studentService.createStudent(student);
assertThat(returnedStudent).isEqualTo(student);
}
}
StudentService
package com.mdv.secondservice.service;
import com.mdv.secondservice.api.dto.ThirdServiceStudentDto;
import com.mdv.secondservice.api.proxy.ThirdServiceProxy;
import com.mdv.secondservice.db.model.Student;
import com.mdv.secondservice.db.repository.StudentRepository;
import feign.FeignException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.ConversionService;
import org.springframework.stereotype.Service;
@Service
@Slf4j
@RequiredArgsConstructor
public class StudentService {
private final StudentRepository studentRepository;
private final ConversionService conversionService;
private final ThirdServiceProxy thirdServiceProxy;
public Student createStudent(Student student) throws FeignException.InternalServerError {
ThirdServiceStudentDto thirdServiceStudentDto =
conversionService.convert(student, ThirdServiceStudentDto.class);
Student createdStudent = thirdServiceProxy.createStudent(thirdServiceStudentDto);
createdStudent.setMiddleName(student.getMiddleName());
studentRepository.save(createdStudent);
return createdStudent;
}
}
It seems like I messed up with matchers in the first when call. I know I didn't mock StudentRepository, I will fix that later. The problem is that conversionService.convert(...) returns null when called in StudentService.createStudent method.
UPD (added Mockito error):
java.lang.NullPointerException
at com.mdv.secondservice.service.StudentService.createStudent(StudentService.java:26)
at com.mdv.secondservice.StudentServiceTests.createStudent_StudentWasCreated(StudentServiceTests.java:59)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Suppressed: org.mockito.exceptions.misusing.UnnecessaryStubbingException:
Unnecessary stubbings detected.
Clean & maintainable test code requires zero unnecessary code.
Following stubbings are unnecessary (click to navigate to relevant line of code):
1. -> at com.mdv.secondservice.StudentServiceTests.createStudent_StudentWasCreated(StudentServiceTests.java:56)
2. -> at com.mdv.secondservice.StudentServiceTests.createStudent_StudentWasCreated(StudentServiceTests.java:58)
Please remove unnecessary stubbings or use 'lenient' strictness. More info: javadoc for UnnecessaryStubbingException class.
at org.mockito.junit.jupiter.MockitoExtension.afterEach(MockitoExtension.java:181)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAfterEachCallbacks$11(TestMethodTestDescriptor.java:255)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$12(TestMethodTestDescriptor.java:271)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeAllAfterMethodsOrCallbacks$13(TestMethodTestDescriptor.java:271)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAllAfterMethodsOrCallbacks(TestMethodTestDescriptor.java:270)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeAfterEachCallbacks(TestMethodTestDescriptor.java:254)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:143)
... 41 more
答案1
得分: 1
当你模拟一切时,你不需要Spring Boot上下文。
你可以删除@SpringBootTest
。
然后你的示例应该可以运行。
否则,你可以用@ExtendWith(SpringExtension.class)
替换@ExtendWith(MockitoExtension.class)
。
英文:
When you mock everything, you dont need the spring boot context.
You can delete the @SpringBootTest
.
And your example should run.
Otherwise you can replace @ExtendWith(MockitoExtension.class)
with
@ExtendWith(SpringExtension.class)
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论