JSONObject 预期在路径 $ 中找到 [属性 ['XXX'] 的对象
JSONObject Expected to find an object with property ['XXX'] in path $
我做了一个消费第三方的程序API:我有一个服务Called:NewsService
@Service
public class NewsService {
@Autowired
private NewsRepository newsRepository;
public List<News> getTopStories() throws Exception{
RestTemplate restTemplate = new RestTemplate();
JSONObject news = new JSONObject();
NewsStories newsentity = new NewsStories();
List<News> stories = new ArrayList<News>();
ObjectMapper mapper = new ObjectMapper();
String getUrl = "https://api.nytimes.com/svc/topstories/v2/home.json?api-key=84e19f8ee1c7489a97481d2ed85af15c";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map> entity = new HttpEntity<Map>(headers);
ResponseEntity<Map> newsList = restTemplate.exchange(getUrl, HttpMethod.GET, entity, Map.class);
if (newsList.getStatusCode() == HttpStatus.OK) {
news = new JSONObject(newsList.getBody());
newsentity = mapper.readValue(news.toString(),NewsStories.class);
newsentity.getStories().forEach(stories::add);
}
return stories;
}
}`
我有控制器
@RestController
@RequestMapping("/api/")
public class NewsController {
@Autowired
NewsService newsService = new NewsService();
@RequestMapping(value = "/news/topstories", method = RequestMethod.GET)
public @ResponseBody List<News> getNews() throws Exception {
return this.newsService.getTopStories();
}
}`
一切正常,但是当我 运行 进行我的测试时(我无法通过内部审计控制更改它)这是我的测试。
@SpringBootTest
@RunWith(SpringRunner.class)
public class ProjectApplicationTests {
private MockMvc mockMvc;
@Autowired
WebApplicationContext context;
@Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
public void Newstest_ok() throws Exception {
mockMvc.perform(get("/api/news/topstories" )).andDo(print())
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.title").exists())
.andExpect(MockMvcResultMatchers.jsonPath("$.section").exists());
}`
在 运行 程序旁边 我的程序中存在检查验证 Exist() 的问题。你可以帮帮我吗? 运行t 测试后的日志下方。
2018-07-18 09:40:49.100 INFO 23324 --- [ main]
o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring
FrameworkServlet '' 2018-07-18 09:40:49.100 INFO 23324 --- [
main] o.s.t.web.servlet.TestDispatcherServlet : FrameworkServlet '':
initialization started 2018-07-18 09:40:49.116 INFO 23324 --- [
main] o.s.t.web.servlet.TestDispatcherServlet : FrameworkServlet '':
initialization completed in 16 ms MockHttpServletRequest:
HTTP Method = GET
Request URI = /api/news/topstories
Parameters = {}
Headers = {}
Body =
Session Attrs = {} Handler:
Type = com.example.project.Web.NewsController
Method = public java.util.List
com.example.project.Web.NewsController.getNews() throws
java.lang.Exception Async:
Async started = false
Async result = null Resolved Exception:
Type = null ModelAndView:
View name = null
View = null
Model = null FlashMap:
Attributes = null MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = [{"title":"Donald Trump, Barack Obama, European Union: Your Wednesday Briefing","section":"Briefing"},{"title":"New
York Today: Will Green Roofs Get the Green Light?","section":"New
York"},{"title":"California Today: Will a Representative’s Views on
Russia Affect His Re-election Campaign?","section":"U.S."},{"title":"A
Besieged Trump Says He Misspoke on Russian Election
Meddling","section":"World"}]
Forwarded URL = null Redirected URL = null
Cookies = [] java.lang.AssertionError: No value at JSON path "$.title" at
org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:290)
at
org.springframework.test.util.JsonPathExpectationsHelper.assertExistsAndReturn(JsonPathExpectationsHelper.java:306)
at
org.springframework.test.util.JsonPathExpectationsHelper.exists(JsonPathExpectationsHelper.java:184)
at
org.springframework.test.web.servlet.result.JsonPathResultMatchers.lambda$exists(JsonPathResultMatchers.java:123)
at
org.springframework.test.web.servlet.MockMvc.andExpect(MockMvc.java:178)
at
com.example.project.ProjectApplicationTests.Newstest_ok(ProjectApplicationTests.java:44)
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.runReflectiveCall(FrameworkMethod.java:50)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at
org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at
org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at
org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at
org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at
org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290) at
org.junit.runners.ParentRunner.schedule(ParentRunner.java:71) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at
org.junit.runners.ParentRunner.access[=15=]0(ParentRunner.java:58) at
org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268) at
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at
com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
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)
Caused by: com.jayway.jsonpath.PathNotFoundException: Expected to find
an object with property ['title'] in path $ but found
'net.minidev.json.JSONArray'. This is not a json object according to
the JsonProvider:
'com.jayway.jsonpath.spi.json.JsonSmartJsonProvider'. at
com.jayway.jsonpath.internal.path.PropertyPathToken.evaluate(PropertyPathToken.java:71)
at
com.jayway.jsonpath.internal.path.RootPathToken.evaluate(RootPathToken.java:62)
at
com.jayway.jsonpath.internal.path.CompiledPath.evaluate(CompiledPath.java:53)
at
com.jayway.jsonpath.internal.path.CompiledPath.evaluate(CompiledPath.java:61)
at com.jayway.jsonpath.JsonPath.read(JsonPath.java:187) at
com.jayway.jsonpath.JsonPath.read(JsonPath.java:345) at
com.jayway.jsonpath.JsonPath.read(JsonPath.java:329) at
org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:286)
... 36 more
`
使用 Postman http://localhost:8080/api/news/topstories 我得到 Json 数据
状态为 200 正常。
根据 JSON 响应,我们可以看到控制器正在返回主体作为对象的 Array。
要访问 Spring MVC 测试中的每个对象,请使用以下断言:
.andExpect(jsonPath("[0].title").value("titlevalue0"))
.andExpect(jsonPath("[1].title").value("titlevalue1"))
这是使用 json 路径提取器的完整解决方案,使用简单的 java 程序:jar:- json-path-2.2.0.jar, json-simple-1.1.1.jar, slf4j-log4j12-1.7.5.jar
yourjsonfile.json
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
public class Readjson {
public static void main(String[] args) throws FileNotFoundException, IOException, ParseException {
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader("yourjsonfile.json"));
Object res = JsonPath.read(obj, "$..title");
System.out.println(res);
}
}
["Sayings of the Century","Sword of Honour","Moby Dick","The Lord of the Rings"]
我解决了 Hackerrank 测试用例问题,如下所示。
@RestController
@RequestMapping("/api/news/")
public class NewsController {
@Autowired
NewsService newsService;
@RequestMapping("/topstories")
public String getNews() throws Exception{
JSONObject news = newsService.getTopStories();
return news.toString();
}
}
@Service
public class NewsService {
private String apiKey = "<Replace ur api key>";
public JSONObject getTopStories() throws Exception {
List<News> topStories = new ArrayList<>();
RestTemplate restTemplate = new RestTemplate();
String getUrl = "https://api.nytimes.com/svc/topstories/v2/science.json?api-key=" + apiKey;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<Map> newsList = restTemplate.exchange(getUrl, HttpMethod.GET, entity, Map.class);
JSONObject jsonObject=null;
if (newsList.getStatusCode() == HttpStatus.OK) {
jsonObject = new JSONObject(newsList.getBody());
}
return jsonObject;
}
我做了一个消费第三方的程序API:我有一个服务Called:NewsService
@Service
public class NewsService {
@Autowired
private NewsRepository newsRepository;
public List<News> getTopStories() throws Exception{
RestTemplate restTemplate = new RestTemplate();
JSONObject news = new JSONObject();
NewsStories newsentity = new NewsStories();
List<News> stories = new ArrayList<News>();
ObjectMapper mapper = new ObjectMapper();
String getUrl = "https://api.nytimes.com/svc/topstories/v2/home.json?api-key=84e19f8ee1c7489a97481d2ed85af15c";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map> entity = new HttpEntity<Map>(headers);
ResponseEntity<Map> newsList = restTemplate.exchange(getUrl, HttpMethod.GET, entity, Map.class);
if (newsList.getStatusCode() == HttpStatus.OK) {
news = new JSONObject(newsList.getBody());
newsentity = mapper.readValue(news.toString(),NewsStories.class);
newsentity.getStories().forEach(stories::add);
}
return stories;
}
}`
我有控制器
@RestController
@RequestMapping("/api/")
public class NewsController {
@Autowired
NewsService newsService = new NewsService();
@RequestMapping(value = "/news/topstories", method = RequestMethod.GET)
public @ResponseBody List<News> getNews() throws Exception {
return this.newsService.getTopStories();
}
}`
一切正常,但是当我 运行 进行我的测试时(我无法通过内部审计控制更改它)这是我的测试。
@SpringBootTest
@RunWith(SpringRunner.class)
public class ProjectApplicationTests {
private MockMvc mockMvc;
@Autowired
WebApplicationContext context;
@Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
@Test
public void Newstest_ok() throws Exception {
mockMvc.perform(get("/api/news/topstories" )).andDo(print())
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.title").exists())
.andExpect(MockMvcResultMatchers.jsonPath("$.section").exists());
}`
在 运行 程序旁边 我的程序中存在检查验证 Exist() 的问题。你可以帮帮我吗? 运行t 测试后的日志下方。
2018-07-18 09:40:49.100 INFO 23324 --- [ main] o.s.b.t.m.w.SpringBootMockServletContext : Initializing Spring FrameworkServlet '' 2018-07-18 09:40:49.100 INFO 23324 --- [
main] o.s.t.web.servlet.TestDispatcherServlet : FrameworkServlet '': initialization started 2018-07-18 09:40:49.116 INFO 23324 --- [
main] o.s.t.web.servlet.TestDispatcherServlet : FrameworkServlet '': initialization completed in 16 ms MockHttpServletRequest: HTTP Method = GET Request URI = /api/news/topstories Parameters = {} Headers = {} Body = Session Attrs = {} Handler: Type = com.example.project.Web.NewsController Method = public java.util.List com.example.project.Web.NewsController.getNews() throws java.lang.Exception Async: Async started = false Async result = null Resolved Exception: Type = null ModelAndView: View name = null View = null Model = null FlashMap: Attributes = null MockHttpServletResponse: Status = 200 Error message = null Headers = {Content-Type=[application/json;charset=UTF-8]} Content type = application/json;charset=UTF-8 Body = [{"title":"Donald Trump, Barack Obama, European Union: Your Wednesday Briefing","section":"Briefing"},{"title":"New York Today: Will Green Roofs Get the Green Light?","section":"New York"},{"title":"California Today: Will a Representative’s Views on Russia Affect His Re-election Campaign?","section":"U.S."},{"title":"A Besieged Trump Says He Misspoke on Russian Election Meddling","section":"World"}] Forwarded URL = null Redirected URL = null Cookies = [] java.lang.AssertionError: No value at JSON path "$.title" at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:290) at org.springframework.test.util.JsonPathExpectationsHelper.assertExistsAndReturn(JsonPathExpectationsHelper.java:306) at org.springframework.test.util.JsonPathExpectationsHelper.exists(JsonPathExpectationsHelper.java:184) at org.springframework.test.web.servlet.result.JsonPathResultMatchers.lambda$exists(JsonPathResultMatchers.java:123) at org.springframework.test.web.servlet.MockMvc.andExpect(MockMvc.java:178) at com.example.project.ProjectApplicationTests.Newstest_ok(ProjectApplicationTests.java:44) 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.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73) at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97) at org.junit.runners.ParentRunner.run(ParentRunner.java:290) at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access[=15=]0(ParentRunner.java:58) at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) 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) Caused by: com.jayway.jsonpath.PathNotFoundException: Expected to find an object with property ['title'] in path $ but found 'net.minidev.json.JSONArray'. This is not a json object according to the JsonProvider: 'com.jayway.jsonpath.spi.json.JsonSmartJsonProvider'. at com.jayway.jsonpath.internal.path.PropertyPathToken.evaluate(PropertyPathToken.java:71) at com.jayway.jsonpath.internal.path.RootPathToken.evaluate(RootPathToken.java:62) at com.jayway.jsonpath.internal.path.CompiledPath.evaluate(CompiledPath.java:53) at com.jayway.jsonpath.internal.path.CompiledPath.evaluate(CompiledPath.java:61) at com.jayway.jsonpath.JsonPath.read(JsonPath.java:187) at com.jayway.jsonpath.JsonPath.read(JsonPath.java:345) at com.jayway.jsonpath.JsonPath.read(JsonPath.java:329) at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:286) ... 36 more
`
使用 Postman http://localhost:8080/api/news/topstories 我得到 Json 数据 状态为 200 正常。
根据 JSON 响应,我们可以看到控制器正在返回主体作为对象的 Array。
要访问 Spring MVC 测试中的每个对象,请使用以下断言:
.andExpect(jsonPath("[0].title").value("titlevalue0"))
.andExpect(jsonPath("[1].title").value("titlevalue1"))
这是使用 json 路径提取器的完整解决方案,使用简单的 java 程序:jar:- json-path-2.2.0.jar, json-simple-1.1.1.jar, slf4j-log4j12-1.7.5.jar
yourjsonfile.json
{
"store": {
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
"bicycle": {
"color": "red",
"price": 19.95
}
},
"expensive": 10
}
public class Readjson {
public static void main(String[] args) throws FileNotFoundException, IOException, ParseException {
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader("yourjsonfile.json"));
Object res = JsonPath.read(obj, "$..title");
System.out.println(res);
}
}
["Sayings of the Century","Sword of Honour","Moby Dick","The Lord of the Rings"]
我解决了 Hackerrank 测试用例问题,如下所示。
@RestController
@RequestMapping("/api/news/")
public class NewsController {
@Autowired
NewsService newsService;
@RequestMapping("/topstories")
public String getNews() throws Exception{
JSONObject news = newsService.getTopStories();
return news.toString();
}
}
@Service
public class NewsService {
private String apiKey = "<Replace ur api key>";
public JSONObject getTopStories() throws Exception {
List<News> topStories = new ArrayList<>();
RestTemplate restTemplate = new RestTemplate();
String getUrl = "https://api.nytimes.com/svc/topstories/v2/science.json?api-key=" + apiKey;
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(headers);
ResponseEntity<Map> newsList = restTemplate.exchange(getUrl, HttpMethod.GET, entity, Map.class);
JSONObject jsonObject=null;
if (newsList.getStatusCode() == HttpStatus.OK) {
jsonObject = new JSONObject(newsList.getBody());
}
return jsonObject;
}