Mat*_*rne 12 json spring-mvc spring-test spring-test-mvc
我正在使用一个安静的URL来启动长时间运行的后端进程(通常是在cron时间表上,但我们希望能够手动启动它).
下面的代码有效,我在手动测试时会在浏览器中看到结果.
@ResponseBody
@RequestMapping(value = "/trigger/{jobName}", method = RequestMethod.GET)
public Callable<TriggerResult> triggerJob(@PathVariable final String jobName) {
return new Callable<TriggerResult>() {
@Override
public TriggerResult call() throws Exception {
// Code goes here to locate relevant job and kick it off, waiting for result
String message = <result from my job>;
return new TriggerResult(SUCCESS, message);
}
};
}
Run Code Online (Sandbox Code Playgroud)
当我在没有Callable
使用下面的代码的情况下进行测试时,一切正常(我更改了预期的错误消息以简化发布).
mockMvc.perform(get("/trigger/job/xyz"))
.andExpect(status().isOk())
.andDo(print())
.andExpect(jsonPath("status").value("SUCCESS"))
.andExpect(jsonPath("message").value("A meaningful message appears"));
Run Code Online (Sandbox Code Playgroud)
当我添加它Callable
但它不起作用.我也在下面试过,但它没有用.其他人有成功吗?
mockMvc.perform(get("/trigger/job/xyz"))
.andExpect(status().isOk())
.andDo(print())
.andExpect(request().asyncResult(jsonPath("status").value("SUCCESS")))
.andExpect(request().asyncResult(jsonPath("message").value("A meaningful message appears")));
Run Code Online (Sandbox Code Playgroud)
以下是我的print()中的相关部分.看起来mockMvc在这种情况下无法正确解开Json(即使它在我的浏览器中有效)?当我这样做而没有Callable
看到完整的JSON.
MockHttpServletRequest:
HTTP Method = GET
Request URI = /trigger/job/xyz
Parameters = {}
Headers = {}
Handler:
Type = foo.bar.web.controller.TriggerJobController
Method = public java.util.concurrent.Callable<foo.bar.myproject.web.model.TriggerResult> foo.bar.myproject.web.controller.TriggerJobController.triggerJob(java.lang.String)
Async:
Was async started = true
Async result = foo.bar.myproject.web.model.TriggerResult@67aa1e71
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
MockHttpServletResponse:
Status = 200
Error message = null
Headers = {}
Content type = null
Body =
Forwarded URL = null
Redirected URL = null
Cookies = []
Run Code Online (Sandbox Code Playgroud)
Mat*_*rne 17
Bud的答案确实帮助我指出了正确的方向,但它并没有完全奏效,因为它没有等待异步结果.自发布此问题以来,spring-mvc-showcase示例(https://github.com/SpringSource/spring-mvc-showcase)已更新.
看起来在调用的第一部分中,当你检索MvcResult时,你需要在asyncResult()上断言,在JSON pojo映射的情况下,你需要在实际类型本身(而不是JSON)上断言.所以我需要将下面的第三行添加到Bud的答案中,然后剩下的就行了.
MvcResult mvcResult = this.mockMvc.perform(get("/trigger/job/xyz"))
.andExpect(request().asyncStarted())
.andExpect(request().asyncResult(instanceOf(TriggerResult.class)))
.andReturn();
this.mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("status").value("SUCCESS"))
.andExpect(jsonPath("message").value("A meaningful message appears"));
Run Code Online (Sandbox Code Playgroud)
注意: instanceOf()
是org.hamcrest.CoreMatchers.instanceOf
.要访问Hamcrest库,请使用最新的hamcrest-library
jar.
对于maven ......
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>LATEST VERSION HERE</version>
<scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
马特的回答是正确的,但我想perform
工作.下面是一个执行方法,可用于测试异步和同步请求.因此,您无需在测试中关注后端如何处理请求.你只对实际的反应感兴趣,对吧?
ResultActions perform(MockHttpServletRequestBuilder builder) throws Exception {
ResultActions resultActions = mockMvc.perform(builder);
if (resultActions.andReturn().getRequest().isAsyncStarted()) {
return mockMvc.perform(asyncDispatch(resultActions
.andExpect(request().asyncResult(anything()))
.andReturn()));
} else {
return resultActions;
}
}
Run Code Online (Sandbox Code Playgroud)
将其集成到测试中的一种方法是将其放在一个公共抽象基类中,并从中扩展您的实际测试类:
import static org.hamcrest.Matchers.anything;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
@WebAppConfiguration
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml")
public abstract class AbstractMockMvcTests {
@Autowired
protected WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() throws Exception {
mockMvc = webAppContextSetup(this.wac).build();
}
protected ResultActions perform(MockHttpServletRequestBuilder builder) throws Exception {
ResultActions resultActions = mockMvc.perform(builder);
if (resultActions.andReturn().getRequest().isAsyncStarted()) {
return mockMvc.perform(asyncDispatch(resultActions
.andExpect(request().asyncResult(anything()))
.andReturn()));
} else {
return resultActions;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后通过扩展基类并使用perform方法来实现测试.在此示例中,mockMvc是私有的,可以温和地指导所有未来的测试作者使用自定义执行方法.
@RunWith(SpringJUnit4ClassRunner.class)
public class CallableControllerTests extends AbstractMockMvcTests {
@Test
public void responseBodyAsync() throws Exception {
perform(get("/async/callable/response-body"))
.andExpect(status().isOk())
.andExpect(content().contentType("text/plain;charset=ISO-8859-1"))
.andExpect(content().string("Callable result"));
}
@Test
public void responseBodySync() throws Exception {
perform(get("/sync/foobar/response-body"))
.andExpect(status().isOk())
.andExpect(content().contentType("text/plain;charset=ISO-8859-1"))
.andExpect(content().string("Sync result"));
}
}
Run Code Online (Sandbox Code Playgroud)
我想你想在下面链接的启动异步调用参考代码的结果上使用asyncDispatch
用法涉及首先执行一个启动异步处理的请求:
MvcResult mvcResult = this.mockMvc.perform(get("/trigger/job/xyz"))
.andExpect(request().asyncStarted())
.andReturn();
Run Code Online (Sandbox Code Playgroud)
然后重新使用MvcResult执行异步调度:
this.mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(content().string(.......));
Run Code Online (Sandbox Code Playgroud)
或者在你的情况下
this.mockMvc.perform(asyncDispatch(mvcResult))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("status").value("SUCCESS"))
.andExpect(jsonPath("message").value("A meaningful message appears"));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8015 次 |
最近记录: |