使用 spring-test-mvc 框架进行 Spring REST 控制器测试
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9155527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring REST Controller Test with spring-test-mvc framework
提问by jsf
This question is next to the question I had asked here. I am using spring-test-mvcframework to test RESTcontroller. Please see the above link to see my code for the REST Controller I have.
这个问题与我在这里提出的问题相邻。我正在使用spring-test-mvc框架来测试REST控制器。请参阅上面的链接以查看我拥有的 REST 控制器的代码。
My test for GETis working fine but I can't do a POST. I get an exception when I try do so. This is my first time testing a REST controller.
我对GET 的测试工作正常,但我不能做POST。当我尝试这样做时,我得到了一个例外。这是我第一次测试 REST 控制器。
Here's my PcUserControllerTest class
这是我的 PcUserControllerTest 类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/applicationContextTest.xml")
public class PcUserControllerTest {
@Autowired
PcUserService pcUserService;
@Autowired
PcUserController pcUserController;
PcUser pcUser;
private MockMvc mockMvc;
@Before
public void setUp() throws Exception {
mockMvc = standaloneSetup(pcUserController).build();
pcUser = new PcUser("John", "Li", "Weasley", "john", "john");
pcUserService.create(pcUser);
}
@After
public void tearDown() throws Exception {
pcUserService.delete(pcUser.getId());
}
@Test
public void shouldGetPcUser() throws Exception {
this.mockMvc.perform(get("/pcusers/" + pcUser.getId()).accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk());
}
@Test
public void shouldCreatePcUser() throws Exception {
PcUser newUser = new PcUser("Mike", "Li", "Donald", "mike", "mike");
this.mockMvc.perform(post("/pcusers/create/" + newUser).accept(MediaType.APPLICATION_JSON)).andExpect(status().isOk());
}
}
Exception I get when I execute shouldCreatePcUser:
执行 shouldCreatePcUser 时出现异常:
java.lang.IllegalArgumentException: Not enough variable values available to expand ["firstName"]
at org.springframework.web.util.UriComponents$VarArgsTemplateVariables.getValue(UriComponents.java:1011)
at org.springframework.web.util.UriComponents.expandUriComponent(UriComponents.java:443)
at org.springframework.web.util.UriComponents.access(UriComponents.java:431)
at org.springframework.web.util.UriComponents$FullPathComponent.expand(UriComponents.java:790)
at org.springframework.web.util.UriComponents.expandInternal(UriComponents.java:413)
at org.springframework.web.util.UriComponents.expand(UriComponents.java:404)
at org.springframework.web.util.UriTemplate.expand(UriTemplate.java:121)
at org.springframework.test.web.server.request.MockMvcRequestBuilders.expandUrl(MockMvcRequestBuilders.java:51)
at org.springframework.test.web.server.request.MockMvcRequestBuilders.request(MockMvcRequestBuilders.java:45)
at org.springframework.test.web.server.request.MockMvcRequestBuilders.post(MockMvcRequestBuilders.java:28)
at com.project.cleaner.controller.test.PcUserControllerTest.shouldCreatePcUser(PcUserControllerTest.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access@Document
public class PcUser extends BaseEntity {
private String firstName;
private String middleName;
private String lastName;
private String username;
private String password;
public PcUser() {
super();
}
public PcUser(String firstName, String middleName, String lastName,
String username, String password) {
super();
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
this.username = username;
this.password = password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getMiddleName() {
return middleName;
}
public void setMiddleName(String middleName) {
this.middleName = middleName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
// JSONObject jsonPcUser = new JSONObject();
// jsonPcUser.put("id", this.getId());
// jsonPcUser.put("firstName", this.firstName);
// jsonPcUser.put("middleName", this.middleName);
// jsonPcUser.put("lastName", this.lastName);
// jsonPcUser.put("username", this.username);
//
// return jsonPcUser.toJSONString();
return "{\"firstName\":" + this.firstName + ", "
+ "\"middleName\":" + this.middleName + ", "
+ "\"lastName\":" + this.lastName + ", "
+ "\"username\":" + this.username
+ "}";
}
}
0(ParentRunner.java:42)
at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
My PcUser looks like
我的 PcUser 看起来像
public class BaseEntity {
@Id
private String id;
public BaseEntity() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
BaseEntity:
基础实体:
get("/pcusers/" + pcUser.getId())
I don't understand this exception. If anyone could guide me in the right direction would be really appreciated.
我不明白这个例外。如果有人能指导我朝着正确的方向前进,我将不胜感激。
采纳答案by beerbajay
Okay, you have this as your get:
好的,你有这个作为你的get:
PcUser newUser = new PcUser("Mike", "Li", "Donald", "mike", "mike");
post("/pcusers/create/" + newUser)
Which makes sense, because you want to get the resource at /pcusers/123/, but then you have:
这是有道理的,因为您想在 处获取资源/pcusers/123/,但是您有:
PcUser newUser = new PcUser("Mike", "Li", "Donald", "mike", "mike");
this.mockMvc.perform(post("/pcusers/create/")
.content(newUser.toString()) // <-- sets the request content !
.accept(MediaType.APPLICATION_JSON)
.andExpect(status().isOk());
Which doesn't really make sense since you'll be performing a toString()on the newUserobject, then concatenating that with the /pcusers/create/string. So you're probably doing a request to something like /pcusers/create/com.mycompany.PcUser@1596138, which is probably not what you want.
这实际上没有意义,因为您将toString()在newUser对象上执行 a ,然后将其与/pcusers/create/字符串连接。因此,您可能正在向诸如 之类的东西发出请求/pcusers/create/com.mycompany.PcUser@1596138,这可能不是您想要的。
回答by Ytsejammer
It seems, as beerbajay mentions, that the problem is that what you are trying to post to your controller is a PcUser as a URL/path parameter instead of in the actual body of the HTTP request.
正如 beerbajay 所提到的,问题似乎是您尝试发布到控制器的是 PcUser 作为 URL/路径参数,而不是在 HTTP 请求的实际正文中。
I am using the org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder#content(String)method to set the body of the HTTP request itself (as opposed to substitute parts of the URL or add URL parameters) like this:
我正在使用org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder#content(String)方法来设置 HTTP 请求本身的主体(而不是替换部分 URL 或添加 URL 参数),如下所示:
##代码##
![无法为 XML 架构命名空间找到 Spring NamespaceHandler [http://cxf.apache.org/jaxrs]](/res/img/loading.gif)