如何使用 spring boot 和 mockito 对控制器方法进行单元测试
How to unit test a controller method with spring boot and mockito
我已经阅读了几篇文章并观看了一些视频,虽然我掌握了 Mockito 的工作原理,但我仍然无法对我的控制器实施任何测试。
首先,我有以下服务 class,它向外部 API 执行请求:
@Service
public class MovieService {
RestTemplate restTemplate = new RestTemplate();
public MovieResponse getMovieResponse() {
ResponseEntity<MovieResponse> responseEntity = restTemplate.
getForEntity("{base_url}", MovieResponse.class);
return responseEntity.getBody();
}
}
然后我的controller调用这个方法对数据进行排序操作:
@RestController
public class MovieController {
@Autowired
MovieService movieService = new MovieService();
@GetMapping(value="/movies")
public List<Movie> getAllMovies() {
List<Movie> movies = movieService.getMovieResponse().getMovies();
movies.sort(Comparator.comparing(Movie::getMovieName));
return movies ;
}
}
所以我尝试模拟服务响应以测试我的方法并验证排序是否正在进行。
@RunWith(MockitoJUnitRunner.class)
class MovieControllerTest{
private MovieService movieService;
@Autowired
private MockMvc mockMvc;
@Before
void setup() {
movieService = Mockito.mock(MovieService.class);
}
@Test
void getAllMoviesTest() throws Exception {
Movie movie1 = new Movie("Marley & Me", "2008");
Movie movie2 = new Movie("Avatar", "2012");
List<Movie> allMovies = Arrays.asList(movie2, movie1);
List<Movie> expectedMovies = Arrays.asList(movie1, movie2);
MovieResponse firstMovieResponse = new MovieResponse();
firstMovieResponse.setMovies(allMovies);
MovieResponse expectedMovieResponse = new MovieResponse();
firstMovieResponse.setMovies(expectedMovies);
Mockito.when(movieService.getMovieResponse())
.thenReturn(firstMovieResponse);
mockMvc.perform(get("/movies"))
.andExpect(status().isOk())
.andExpect((ResultMatcher) expectedMovieResponse);
}
}
我尝试了几种方法,但我认为这是我所拥有的最接近的方法,但我在行中得到了 NullPointerException
:
Mockito.when(movieService.getMovieResponse())
.thenReturn(firstMovieResponse);
并且堆栈跟踪打印以下内容:
java.lang.NullPointerException
at com.example.movieservice.controller.MovieControllerTest.getAllMoviesTest(MovieControllerTest.java:50)
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:688)
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[=15=](ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke[=15=](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(TestMethodTestDescriptor.java:210)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(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(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:143)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:143)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
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.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute[=15=](EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:84)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:768)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
您需要在@Before注解的设置函数中的getAllMoviesTest中进行设置。您还需要在测试中使用 @MockBean 注释 movieService class 但正如之前有人所说,查看堆栈跟踪以找出发生 NullPointerException 的位置。
我认为 NPE 即将到来,因为 movieservice 没有被模拟并且 movieService 对象可能为空,所以它可能会产生 NPE。尝试将@MockBean 放在移动服务之上。
尝试 运行 在调试模式下进行测试。
如果您的目标是控制排名,这可能会派上用场。
@RunWith(MockitoJUnitRunner.class)
class MovieControllerTest{
@InjectMocks
private MovieController movieController;
@Mock
private MovieService movieService;
@Test
void getAllMoviesTest() throws Exception {
//Given
Movie movie1 = new Movie("Marley & Me", "2008");
Movie movie2 = new Movie("Avatar", "2012");
final List<Movie> allMovies = Arrays.asList(movie2, movie1);
MovieResponse firstMovieResponse = new MovieResponse();
firstMovieResponse.setMovies(allMovies);
Mockito.when(movieService.getMovieResponse()).thenReturn(firstMovieResponse);
//When
List<Movie> actualMovieList = movieController.getAllMovies();
//Then
assertThat(actualMovieList).containsExactly(movie1, movie2);
}
}
@InjectMocks,将模拟 class 注入测试 class.
PS。您还可以使用不同的东西来测试排序。
assertThat(actualMovieList).containsExactly(movie1, movie2);
通常单元测试意味着直接调用主题 class 并存根其依赖项。提供的代码示例依赖于 @Autowired
注释,需要存在 Spring 上下文才能工作。
测试用例尝试调用不可用的 mockMvc
,因此抛出 NullPointerException
。
您必须使用 @SpringBootTest
显式注释测试 class,以便创建上下文。此外,必须包含 @AutoConfigureMockMvc
以便 MockMvc
可用于自动装配。
最后但同样重要的是,由于我们经常使用 Spring 的上下文,因此我们必须用 Spring 的 @MockBean
包装它,而不是使用普通的 Mockito ,这会将存根注入控制器。
@SpringBootTest
@AutoConfigureMockMvc
class MovieControllerTest {
@MockBean
private MovieService movieService;
@Autowired
private MockMvc mockMvc;
@Test
void getAllMoviesTest() throws Exception {
// TODO: when(movieService...).thenReturn(...);
// TODO: mockMvc.perform(...);
}
}
请参阅 Spring's documentation 了解更多信息。
我已经阅读了几篇文章并观看了一些视频,虽然我掌握了 Mockito 的工作原理,但我仍然无法对我的控制器实施任何测试。
首先,我有以下服务 class,它向外部 API 执行请求:
@Service
public class MovieService {
RestTemplate restTemplate = new RestTemplate();
public MovieResponse getMovieResponse() {
ResponseEntity<MovieResponse> responseEntity = restTemplate.
getForEntity("{base_url}", MovieResponse.class);
return responseEntity.getBody();
}
}
然后我的controller调用这个方法对数据进行排序操作:
@RestController
public class MovieController {
@Autowired
MovieService movieService = new MovieService();
@GetMapping(value="/movies")
public List<Movie> getAllMovies() {
List<Movie> movies = movieService.getMovieResponse().getMovies();
movies.sort(Comparator.comparing(Movie::getMovieName));
return movies ;
}
}
所以我尝试模拟服务响应以测试我的方法并验证排序是否正在进行。
@RunWith(MockitoJUnitRunner.class)
class MovieControllerTest{
private MovieService movieService;
@Autowired
private MockMvc mockMvc;
@Before
void setup() {
movieService = Mockito.mock(MovieService.class);
}
@Test
void getAllMoviesTest() throws Exception {
Movie movie1 = new Movie("Marley & Me", "2008");
Movie movie2 = new Movie("Avatar", "2012");
List<Movie> allMovies = Arrays.asList(movie2, movie1);
List<Movie> expectedMovies = Arrays.asList(movie1, movie2);
MovieResponse firstMovieResponse = new MovieResponse();
firstMovieResponse.setMovies(allMovies);
MovieResponse expectedMovieResponse = new MovieResponse();
firstMovieResponse.setMovies(expectedMovies);
Mockito.when(movieService.getMovieResponse())
.thenReturn(firstMovieResponse);
mockMvc.perform(get("/movies"))
.andExpect(status().isOk())
.andExpect((ResultMatcher) expectedMovieResponse);
}
}
我尝试了几种方法,但我认为这是我所拥有的最接近的方法,但我在行中得到了 NullPointerException
:
Mockito.when(movieService.getMovieResponse())
.thenReturn(firstMovieResponse);
并且堆栈跟踪打印以下内容:
java.lang.NullPointerException
at com.example.movieservice.controller.MovieControllerTest.getAllMoviesTest(MovieControllerTest.java:50)
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:688)
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[=15=](ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke[=15=](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(TestMethodTestDescriptor.java:210)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(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(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:143)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:143)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
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.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute[=15=](EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:84)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:768)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
您需要在@Before注解的设置函数中的getAllMoviesTest中进行设置。您还需要在测试中使用 @MockBean 注释 movieService class 但正如之前有人所说,查看堆栈跟踪以找出发生 NullPointerException 的位置。
我认为 NPE 即将到来,因为 movieservice 没有被模拟并且 movieService 对象可能为空,所以它可能会产生 NPE。尝试将@MockBean 放在移动服务之上。 尝试 运行 在调试模式下进行测试。
如果您的目标是控制排名,这可能会派上用场。
@RunWith(MockitoJUnitRunner.class)
class MovieControllerTest{
@InjectMocks
private MovieController movieController;
@Mock
private MovieService movieService;
@Test
void getAllMoviesTest() throws Exception {
//Given
Movie movie1 = new Movie("Marley & Me", "2008");
Movie movie2 = new Movie("Avatar", "2012");
final List<Movie> allMovies = Arrays.asList(movie2, movie1);
MovieResponse firstMovieResponse = new MovieResponse();
firstMovieResponse.setMovies(allMovies);
Mockito.when(movieService.getMovieResponse()).thenReturn(firstMovieResponse);
//When
List<Movie> actualMovieList = movieController.getAllMovies();
//Then
assertThat(actualMovieList).containsExactly(movie1, movie2);
}
}
@InjectMocks,将模拟 class 注入测试 class.
PS。您还可以使用不同的东西来测试排序。
assertThat(actualMovieList).containsExactly(movie1, movie2);
通常单元测试意味着直接调用主题 class 并存根其依赖项。提供的代码示例依赖于 @Autowired
注释,需要存在 Spring 上下文才能工作。
测试用例尝试调用不可用的 mockMvc
,因此抛出 NullPointerException
。
您必须使用 @SpringBootTest
显式注释测试 class,以便创建上下文。此外,必须包含 @AutoConfigureMockMvc
以便 MockMvc
可用于自动装配。
最后但同样重要的是,由于我们经常使用 Spring 的上下文,因此我们必须用 Spring 的 @MockBean
包装它,而不是使用普通的 Mockito ,这会将存根注入控制器。
@SpringBootTest
@AutoConfigureMockMvc
class MovieControllerTest {
@MockBean
private MovieService movieService;
@Autowired
private MockMvc mockMvc;
@Test
void getAllMoviesTest() throws Exception {
// TODO: when(movieService...).thenReturn(...);
// TODO: mockMvc.perform(...);
}
}
请参阅 Spring's documentation 了解更多信息。