Spring Boot测试报错:JSON Path "$.echo"无值及404问题求助
问题求助:Spring MVC测试返回404且JsonPath断言失败
核心报错
java.lang.AssertionError: No value at JSON path "$.echo"
控制台输出
MockHttpServletResponse: Status = 404 Error message = null Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers"] Content type = null Body = Forwarded URL = null Redirected URL = null Cookies = []
问题说明
已搜索JsonPath相关问题并做修改,但问题仍未解决。已实现Service层,但测试时依然返回404,且JsonPath断言失败。
相关代码
测试类
package com.hackerrank.sample; import com.hackerrank.sample.dto.StringResponse; import com.hackerrank.sample.service.HelloService; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.web.servlet.MockMvc; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) @AutoConfigureMockMvc public class SampleApplicationTests { @Autowired private MockMvc mockMvc; @MockBean HelloService helloService; @Before public void setup() { } @Test public void defaultHelloTest() throws Exception { when(helloService.getDefaultHello()).thenReturn(new StringResponse("Hello World!")); mockMvc.perform(get("/defaultHello")) .andDo(print()) .andExpect(jsonPath("$.echo").value("Hello World!")) .andExpect( status().isOk()); } }
Controller类
package com.hackerrank.sample.controller; import com.hackerrank.sample.dto.StringResponse; import com.hackerrank.sample.service.HelloService; import org.springframework.web.bind.annotation.*; @RestController public class SampleController { HelloService helloService; public SampleController(HelloService service) { this.helloService = service; } @GetMapping(value = {"/defaultHello/{message}"}) public StringResponse getDefaultHello(@PathVariable String message) { return helloService.getDefaultHello(message); } @GetMapping(value = {"/defaultHello"}) public StringResponse getDefaultHello() { return helloService.getDefaultHello(); } }
Service接口
package com.hackerrank.sample.service; import com.hackerrank.sample.dto.StringResponse; import org.springframework.stereotype.Repository; import org.springframework.stereotype.Service; @Repository public interface HelloService { public StringResponse getDefaultHello(); public StringResponse getDefaultHello(String message); }
Service实现类
package com.hackerrank.sample.service; import com.hackerrank.sample.dto.StringResponse; import org.springframework.stereotype.Service; @Service public class HelloServiceImpl implements HelloService { private StringResponse stringResponse; public HelloServiceImpl(StringResponse stringResponse) { this.stringResponse = stringResponse; } @Override public StringResponse getDefaultHello() { return new StringResponse("Hello World!"); } @Override public StringResponse getDefaultHello(String message) { return new StringResponse("Hello + " + message); } }
问题分析与解决办法
核心问题
控制台返回404是因为Spring无法正确创建HelloServiceImpl实例,导致SampleController无法被初始化注册,请求找不到对应接口。进而因为没有响应体,JsonPath断言$.echo自然找不到值,抛出错误。
具体原因:
HelloServiceImpl的构造函数依赖StringResponse,但StringResponse是普通DTO,未被Spring注册为Bean,Spring无法注入该依赖,导致Service实例创建失败。HelloService接口错误标注了@Repository注解,该注解用于数据访问层,不适合标注在业务Service接口上。
修复步骤
- 修改
HelloServiceImpl构造函数:移除对StringResponse的依赖,因为实现代码中并未使用该成员变量,直接改为无参构造:
@Service public class HelloServiceImpl implements HelloService { public HelloServiceImpl() { } @Override public StringResponse getDefaultHello() { return new StringResponse("Hello World!"); } @Override public StringResponse getDefaultHello(String message) { return new StringResponse("Hello + " + message); } }
- 修正
HelloService接口的注解:移除错误的@Repository和@Service注解,业务接口无需额外标注Spring注解:
package com.hackerrank.sample.service; import com.hackerrank.sample.dto.StringResponse; public interface HelloService { StringResponse getDefaultHello(); StringResponse getDefaultHello(String message); }
- (可选)确保Controller依赖注入正常:如果你的Spring版本低于4.3,需要给
SampleController的构造函数添加@Autowired注解,高版本可省略,但添加后兼容性更好:
@RestController public class SampleController { HelloService helloService; @Autowired public SampleController(HelloService service) { this.helloService = service; } // 其余代码不变 }
完成以上修改后,Spring能正常创建Service和Controller实例,请求会匹配到对应的接口,返回正确的JSON响应,JsonPath断言也能正常执行。
内容的提问来源于stack exchange,提问作者Sgr
相关产品推荐
相关产品推荐

