我在Spring中设置了一个REST应用程序,我希望应用程序从我的Java类中返回JSON对象。我尝试让我的单元测试将响应识别为JSON对象,但它仍然失败。
这是应用程序上下文
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<context:component-scan base-package="com.livingsoup.beaconapp"/>
<!--<bean id="jacksonObjectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperBuilder" />-->
<!-- mvc names pace is to set annotation driven set up check name space and classes-->
<mvc:annotation-driven/>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="defaultContentType" value="application/json"/>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/database"/>
<property name="username" value="user"/>
<property name="password" value="password"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="annotatedClasses">
<list>
<value>com.livingsoup.beaconapp.data.entities.CustomerEntity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="show_sql">true</prop>
</props>
</property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="customerDOA" class="com.livingsoup.beaconapp.data.services.CustomerDOAImpl"/>
</beans>
这是web.xml文件
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Beacon MVC Rest App</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
这是我的控制器
@RestController
@RequestMapping(value = "/student")
public class DataController
{
private CustomerDOA customerDOA;
@Autowired
public DataController(CustomerDOA customerDOA)
{
this.customerDOA = customerDOA;
}
@RequestMapping(value = "/get", method = RequestMethod.GET)
public @ResponseBody
Student getData()
{
Student student = new Student();
student.setName("Hello World");
return student;
}
@RequestMapping(value = "/findByPhoneNumber", method = RequestMethod.GET, produces="application/json")
public @ResponseBody CustomerEntity findByPhoneNumber()
{
return customerDOA.findByPhoneNumber("07966487189");
}
这是我的实体
@Entity
@Table(name = "Customer", schema = "", catalog = "iBeaconServiceDB")
public class CustomerEntity
{
private int id;
private String firstName;
private String lastName;
private String phoneNumber;
private String address1;
private String address2;
private String address3;
private String city;
private String postCode;
@Id
@Column(name = "id", nullable = false, insertable = true, updatable = true)
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
@Basic
@Column(name = "first_name", nullable = true, insertable = true, updatable = true, length = 255)
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
@Basic
@Column(name = "last_name", nullable = true, insertable = true, updatable = true, length = 255)
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName = lastName;
}
@Basic
@Column(name = "phone_number", nullable = true, insertable = true, updatable = true, length = 25)
public String getPhoneNumber()
{
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber)
{
this.phoneNumber = phoneNumber;
}
@Basic
@Column(name = "address_1", nullable = true, insertable = true, updatable = true, length = 255)
public String getAddress1()
{
return address1;
}
public void setAddress1(String address1)
{
this.address1 = address1;
}
@Basic
@Column(name = "address_2", nullable = true, insertable = true, updatable = true, length = 255)
public String getAddress2()
{
return address2;
}
public void setAddress2(String address2)
{
this.address2 = address2;
}
@Basic
@Column(name = "address_3", nullable = true, insertable = true, updatable = true, length = 255)
public String getAddress3()
{
return address3;
}
public void setAddress3(String address3)
{
this.address3 = address3;
}
@Basic
@Column(name = "city", nullable = true, insertable = true, updatable = true, length = 255)
public String getCity()
{
return city;
}
public void setCity(String city)
{
this.city = city;
}
@Basic
@Column(name = "post_code", nullable = true, insertable = true, updatable = true, length = 255)
public String getPostCode()
{
return postCode;
}
public void setPostCode(String postCode)
{
this.postCode = postCode;
}
@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CustomerEntity that = (CustomerEntity) o;
if (id != that.id) return false;
if (address1 != null ? !address1.equals(that.address1) : that.address1 != null) return false;
if (address2 != null ? !address2.equals(that.address2) : that.address2 != null) return false;
if (address3 != null ? !address3.equals(that.address3) : that.address3 != null) return false;
if (city != null ? !city.equals(that.city) : that.city != null) return false;
if (firstName != null ? !firstName.equals(that.firstName) : that.firstName != null) return false;
if (lastName != null ? !lastName.equals(that.lastName) : that.lastName != null) return false;
if (phoneNumber != null ? !phoneNumber.equals(that.phoneNumber) : that.phoneNumber != null) return false;
if (postCode != null ? !postCode.equals(that.postCode) : that.postCode != null) return false;
return true;
}
@Override
public int hashCode()
{
int result = id;
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
result = 31 * result + (phoneNumber != null ? phoneNumber.hashCode() : 0);
result = 31 * result + (address1 != null ? address1.hashCode() : 0);
result = 31 * result + (address2 != null ? address2.hashCode() : 0);
result = 31 * result + (address3 != null ? address3.hashCode() : 0);
result = 31 * result + (city != null ? city.hashCode() : 0);
result = 31 * result + (postCode != null ? postCode.hashCode() : 0);
return result;
}
}
这是我的单元测试
public void testGetData() throws Exception
{
CustomerDOA customerDOA = mock(CustomerDOAImpl.class);
DataController controller = new DataController(customerDOA);
MockMvc mockMvc = standaloneSetup(controller).build();
mockMvc.perform(get("/student/findByPhoneNumber"))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"));
}
这是我从单元测试中得到的错误
java.lang.AssertionError: Content type not set
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:39)
at org.springframework.test.util.AssertionErrors.assertTrue(AssertionErrors.java:72)
at org.springframework.test.web.servlet.result.ContentResultMatchers$1.match(ContentResultMatchers.java:80)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:153)
at com.livingsoup.beaconapp.controllers.DataControllerTest.testGetData(DataControllerTest.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
这是从我的单元测试打印出来的响应,我无法理解我做错了什么。为什么我的单元测试不能识别我的JSON输出?
MockHttpServletRequest:
HTTP Method = GET
Request URI = /student/findByPhoneNumber
Parameters = {}
Headers = {}
Handler:
Type = com.livingsoup.beaconapp.controllers.DataController
Method = public com.livingsoup.beaconapp.data.entities.CustomerEntity com.livingsoup.beaconapp.controllers.DataController.findByPhoneNumber()
Async:
Was async started = false
Async result = null
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 = []
答案 0 :(得分:1)
我正在设置我的测试类错误,我没有在我的测试类顶部添加Annotations,而且我本应该将@AutoWired Annotation添加到控制器中并且我还添加了doSetup方法(参见示例)下文)
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml")
@TransactionConfiguration(defaultRollback = true, transactionManager = "txManager")
public class DataControllerTest extends TestCase
{
@Autowired
CustomerController dataController;
MockMvc mockMvc;
@Before
public void doSetup()
{
mockMvc = standaloneSetup(dataController).build();
}
@Test
public void testGetDataParam() throws Exception
{
String phoneNumber = "5551234";
mockMvc.perform(get("/customer/findByPhoneNumber/" + phoneNumber))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)).andDo(print())
.andExpect(jsonPath("$.firstName").value("Russell"))
.andExpect(jsonPath("$.lastName").value("Milburn"));
}
}
答案 1 :(得分:0)
从我看到你的配置看起来没问题。
但是你缺少Accept标头,我不确定spring-mvc是否需要这个标头集来设置内容类型。但你绝对可以配置spring来忽略accept标头。
contentNegotiationManagerFactoryBean.setIgnoreAcceptHeader()
值得一试或只是设置标题。
mockMvc.perform(get('/..').accept(MediaType.APPLICATION_JSON));