Spring单元测试休息控制器错误

Posted

技术标签:

【中文标题】Spring单元测试休息控制器错误【英文标题】:Spring Unit testing rest controller error 【发布时间】:2018-07-31 20:35:15 【问题描述】:

这是我的 UserController,返回所有 UserDto 的 get() 方法。

@GetMapping("/")
public List<UserDto> get() 
    return userService.getUsers().stream().map((User user) -> toUserDto(user)).collect(Collectors.toList());

而且,this 是我的 UserControllerTest 测试这个失败的 get() 方法。你能告诉我我做错了什么吗?我正在迈出测试的第一步。

这是控制台日志:

java.lang.NullPointerException
at pl.rmitula.restfullshop.controller.UserControllerTest.getAll(UserControllerTest.java:43)
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.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:389)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:167)
at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:163)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:110)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:83)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$null$2(HierarchicalTestExecutor.java:92)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:92)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$null$2(HierarchicalTestExecutor.java:92)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.lambda$execute$3(HierarchicalTestExecutor.java:92)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:77)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:51)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:62)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

【问题讨论】:

你需要模拟你的 userService @pvpkiran 你能举个例子吗? 【参考方案1】:

您不是在嘲笑所需的服务。

您需要将 userService 的模拟注入到您的控制器中,并在需要时模拟响应。

@RunWith(MockitoJUnitRunner.class)
class UserControllerTest 

@Mock
private UserService userService;


@InjectMocks
private UserController userController;

private MockMvc mockMvc;

@Before
void setUp() 
    mockMvc = MockMvcBuilders.standaloneSetup(this.userController).build();


@Test
void getAll() throws Exception 
    List<UserDto> userdtos = Arrays.asList(
            new UserDto((long) 1, "John", "Snow", "johnsnow@blackbastard.com", "snow", "password"),
            new UserDto((long) 2, "Tyrion", "Lanister", "tyrion@lannister.com", "tyrion", "password"));

    String url = "/api/users";
    MvcResult mvcResult = mockMvc.perform(get(url)).andExpect(MockMvcResultMatchers.status().isOk()).andReturn();

    Assert.assertEquals("failure", mvcResult.getResponse(), userdtos);


我不是独立方法的忠实拥护者,我发现 WebMvcTest 切片测试清理器可以有效地为您完成设置。

@RunWith(SpringRunner.class)
@WebMvcTest
    class UserControllerTest 

    @MockBean
    private UserService userService;


    @Autowired
    private MockMvc mockMvc;

//tests

【讨论】:

好的,但是这两个例子仍然对我不起作用。我得到了相同的 NullPointerException 和 this code 。你能检查一下吗? 也添加您的完整控制器 你实际上是在模拟某种集合,即使是空的,以返回流? Null 将是默认值。

以上是关于Spring单元测试休息控制器错误的主要内容,如果未能解决你的问题,请参考以下文章

kotlin + Spring boot 中的单元测试休息控制器

使用 spring boot、kotlin 和 junit 进行休息控制器单元测试

用于单元测试的模拟休息模板

Laravel 单元测试显示完全错误

测试一个spring mvc rest控制器

Spring Boot 控制器单元测试:无法加载 ApplicationContext