问题描述
我有一个非常简单的RESTful控制器,该控制器使用并生成JSON.我需要离线测试该控制器,即没有服务器在运行,也没有在数据库运行.而且我为无法找到解决方案而发疯.我的初始测试用例将包括:
I have a very simple RESTful Controller that consumes and produces JSON. I need to test this controller offline i.e. no server running, no database running. And I am going nuts for not being able to find a solution. My intial test cases will include:
- 测试REST URI,即GET,POST,PUT,DELETE-我必须能够根据发送的数据声明返回的数据.
- 声明将测试JSON数据
我有以下URI:
- /pcusers-返回所有用户
- /pcusers/{id}-返回特定用户
- /pcusers/create/{pcuser}-将用户添加到数据库
- /pcusers/update/{pcuser}-更新用户
- /pcusers/delete/{id}-删除用户
注意:这不是典型的MVC应用程序.我没有意见.我有一个纯粹的REST控制器,它发出JSON并使用JSON格式的数据.
NOTE: This is NOT a typical MVC application. I DO NOT have Views. I have a pure REST controller that spits out JSON and consumes data in JSON format.
如果有人可以引导我朝正确的方向前进,将不胜感激.
If someone could guide me in the right direction would be really appreciated.
只是要弄清楚我的代码是什么样的:
Just to be clear how my code looks like:
@Controller
@RequestMapping("/pcusers")
public class PcUserController {
protected static Logger logger = Logger.getLogger(PcUserController.class);
@Resource(name = "pcUserService")
private PcUserService pcUserService;
@RequestMapping(value = "", method = RequestMethod.GET, produces = "application/json")
@ResponseBody
public List<PcUser> readAll() {
logger.debug("Delegating to service to return all PcUsers");
return pcUserService.readAll();
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET, consumes = "application/json", produces = "application/json")
@ResponseBody
public PcUser read(@PathVariable String id) {
logger.debug("Delegating to service to return PcUser " + id);
return pcUserService.read(id);
}
@RequestMapping(value = "/create/{pcUser}", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
@ResponseBody
public boolean create(@PathVariable PcUser pcUser) {
logger.debug("Delegating to service to create new PcUser");
return pcUserService.create(pcUser);
}
@RequestMapping(value = "/update/{pcUser}", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
@ResponseBody
public boolean update(@PathVariable PcUser pcUser) {
logger.debug("Delegating to service to update existing PcUser");
return pcUserService.update(pcUser);
}
@RequestMapping(value = "/delete/{id}", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
@ResponseBody
public boolean delete(@PathVariable String id) {
logger.debug("Delegating to service to delete existing PcUser");
return pcUserService.delete(id);
}
}
更新(2/5/2012):经过研究,我遇到了一个名为 spring-test-mvc 的Spring框架.看起来非常有前途,我已经设法在这方面取得了良好的开端.但是现在我有一个新问题.当我向"/pcusers/{id}"提交GET请求时,控件将传递给负责处理该映射的 read 方法.在该方法内部,我有一个 pcUserService 进行读取.现在,问题是当我运行此测试时,真实控制器内的 pcUserService 实例为NULL;因此,由于无法在NULL对象上调用read而导致崩溃.
UPDATE (2/5/2012):After some research, I came across a Spring framework called spring-test-mvc. It looks very promising and I have managed to get a good start on this. But now I have a new problem. When I submit a GET request to "/pcusers/{id}", the control is passed to read method which is responsible for handling that mapping. Inside that method I have a pcUserService that does a read. Now, the problem is when I run this test, the pcUserService instance inside real controller is NULL; and therefore it ends up crashing as read cannot be called on a NULL object.
以下是 PcUserControllerTest 代码:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/applicationContextTest.xml")
public class PcUserControllerTest {
@Autowired
PcUserService pcUserService;
@Autowired
PcUserController pcUserController;
PcUser pcUser;
@Before
public void setUp() throws Exception {
pcUser = new PcUser("John", "Li", "Weasley", "john", "john", new DateTime());
pcUserService.create(pcUser);
}
public void tearDown() throws Exception {
pcUserService.delete(pcUser.getId());
}
@Test
public void shouldGetPcUser() throws Exception {
standaloneSetup(pcUserController)
.build()
.perform(get("/pcusers/" + pcUser.getId()).accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
}
推荐答案
这里是一个建议,应该给您一些想法.我假设您熟悉SpringJUnit4ClassRunner
和@ContextConfiguration
.首先创建一个包含PcUserController
和模拟的PcUserService
的测试应用程序上下文.在下面的示例PcUserControllerTest
类中,Jackson用于转换JSON消息,而Mockito用于模拟.
Here is one suggestion that should give you some ideas. I assume that you are familiar with the SpringJUnit4ClassRunner
and the @ContextConfiguration
. Start by creating an test application context that contains PcUserController
and a mocked PcUserService
. In the example PcUserControllerTest
class below, Jackson is used to convert JSON messages and Mockito is used for mocking.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(/* Insert test application context here */)
public class PcUserControllerTest {
MockHttpServletRequest requestMock;
MockHttpServletResponse responseMock;
AnnotationMethodHandlerAdapter handlerAdapter;
ObjectMapper mapper;
PcUser pcUser;
@Autowired
PcUserController pcUserController;
@Autowired
PcUserService pcUserServiceMock;
@Before
public void setUp() {
requestMock = new MockHttpServletRequest();
requestMock.setContentType(MediaType.APPLICATION_JSON_VALUE);
requestMock.addHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE);
responseMock = new MockHttpServletResponse();
handlerAdapter = new AnnotationMethodHandlerAdapter();
HttpMessageConverter[] messageConverters = {new MappingJacksonHttpMessageConverter()};
handlerAdapter.setMessageConverters(messageConverters);
mapper = new ObjectMapper();
pcUser = new PcUser(...);
reset(pcUserServiceMock);
}
}
现在,我们拥有创建测试所需的所有代码:
Now, we have all the code needed to create the tests:
@Test
public void shouldGetUser() throws Exception {
requestMock.setMethod("GET");
requestMock.setRequestURI("/pcusers/1");
when(pcUserServiceMock.read(1)).thenReturn(pcUser);
handlerAdapter.handle(requestMock, responseMock, pcUserController);
assertThat(responseMock.getStatus(), is(HttpStatus.SC_OK));
PcUser actualPcUser = mapper.readValue(responseMock.getContentAsString(), PcUser.class);
assertThat(actualPcUser, is(pcUser));
}
@Test
public void shouldCreateUser() throws Exception {
requestMock.setMethod("POST");
requestMock.setRequestURI("/pcusers/create/1");
String jsonPcUser = mapper.writeValueAsString(pcUser);
requestMock.setContent(jsonPcUser.getBytes());
handlerAdapter.handle(requestMock, responseMock, pcUserController);
verify(pcUserServiceMock).create(pcUser);
}
这篇关于Spring Framework TEST RESTful Web服务(控制器)离线,即没有服务器,没有数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!