Java Junit测试用例断言错误应为json字符串

Java Junit测试用例断言错误应为json字符串,java,list,generics,Java,List,Generics,我试图创建一个助手方法,将MockMvc测试的响应体转换回我的域对象,并希望使其对所有对象通用。当响应是一个对象时,它工作,但当它是一个对象列表时,它不工作 我正在使用com.fasterxml.jackson.databind.ObjectMapper和com.fasterxml.jackson.core.type.TypeReference将响应主体映射回我的应用程序对象 以下是将响应映射到对象的方法: protected static <T> List<T> g

我试图创建一个助手方法,将MockMvc测试的响应体转换回我的域对象,并希望使其对所有对象通用。当响应是一个对象时,它工作,但当它是一个对象列表时,它不工作

我正在使用com.fasterxml.jackson.databind.ObjectMapper和com.fasterxml.jackson.core.type.TypeReference将响应主体映射回我的应用程序对象

以下是将响应映射到对象的方法:

  protected static <T> List<T> getResponseBodyList(MockHttpServletResponse response,
      Class<T> clazz) throws JsonParseException, JsonMappingException,
      UnsupportedEncodingException, IOException, InstantiationException, IllegalAccessException {
    TypeReferenceListImpl<T> typeReference = new TypeReferenceListImpl<T>(clazz);
    List<T> responseBody = new ObjectMapper().readValue(response.getContentAsString(),
        typeReference);
    return (List<T>) responseBody;
  }

  protected static <T> T getResponseBody(MockHttpServletResponse response, Class<T> clazz)
      throws JsonParseException, JsonMappingException, UnsupportedEncodingException, IOException {
    TypeReferenceImpl<T> typeReference = new TypeReferenceImpl<T>(clazz);
    T responseBody = new ObjectMapper().readValue(response.getContentAsString(), typeReference);
    return responseBody;
  }

  private static class TypeReferenceImpl<T> extends TypeReference<T> {
    protected final Type type;

    protected TypeReferenceImpl(Class<T> clazz) {
      type = clazz;
    }

    public Type getType() {
      return type;
    }
  }

  private static class TypeReferenceListImpl<T> extends TypeReference<T> {
    protected final Type type;

    protected TypeReferenceListImpl(Class<T> clazz) throws InstantiationException,
        IllegalAccessException {
      List<T> list = new ArrayList<>();
      list.add(clazz.newInstance());
      type = list.getClass();
    }

    public Type getType() {
      return type;
    }
  }
受保护的静态列表getResponseBodyList(MockHttpServletResponse,
类clazz)抛出JsonParseException、JsonMappingException、,
UnsupportedEncodingException、IOException、InstanceionException、IllegalAccessException{
TypeReferenceListImpl typeReference=新的TypeReferenceListImpl(clazz);
List ResponseBy=new ObjectMapper().readValue(response.getContentAsString(),
类型参考);
返回(列表)响应库;
}
受保护的静态T GetResponseBy(MockHttpServletResponse,类clazz)
抛出JsonParseException、JsonMappingException、UnsupportedEncodingException、IOException{
TypeReferenceImpl typeReference=新的TypeReferenceImpl(clazz);
T responseBody=newObjectMapper().readValue(response.getContentAsString(),typeReference);
返回响应体;
}
私有静态类TypeReferenceImpl扩展了TypeReference{
受保护的最终类型;
受保护的TypeReferenceImpl(类clazz){
类型=clazz;
}
公共类型getType(){
返回类型;
}
}
私有静态类TypeReferenceListImpl扩展了TypeReference{
受保护的最终类型;
受保护的TypeReferenceListImpl(类clazz)抛出实例化异常,
非法访问例外{
列表=新的ArrayList();
add(clazz.newInstance());
type=list.getClass();
}
公共类型getType(){
返回类型;
}
}
我在测试中这样调用这些方法:

// This test works: 
  @Test
  public void getUserTest() throws Exception {
    when(applicationUserServiceMock.loadUserByUsername(applicationUser.getUsername())).thenReturn(
        applicationUser);

    MockHttpServletResponse response = executeGet(API_V1_ADMIN_APPLICATION_USERS + applicationUser
        .getUsername());
    ApplicationUser responseBody = getResponseBody(response, ApplicationUser.class);

    verifyResponseStatus(response, HttpStatus.OK.value());
    assertEquals(applicationUser, responseBody);
  }

//Test that fails:
 @Test
  public void getUsersTest() throws Exception {
    when(applicationUserServiceMock.getAllUsers()).thenReturn(applicationUsersList);

    MockHttpServletResponse response = executeGet(API_V1_ADMIN_APPLICATION_USERS); 

    List<ApplicationUser> responseBody = getResponseBodyList(response, ApplicationUser.class);

    verifyResponseStatus(response, HttpStatus.OK.value());
    assertEquals(3, responseBody.size()); // This assert passes
    assertEquals(applicationUsersList, responseBody); 
// Fails in the last assertEquals. Debugging it, I can see responseBody ends up being a List of LinkedHashMaps. 
// I assume because I get a list of Objects instead of a list of ApplicationUsers. 
  }
//此测试有效:
@试验
public void getUserTest()引发异常{
当(applicationUserServiceMock.loadUserByUsername(applicationUser.getUsername())。然后返回(
应用程序用户);
MockHttpServletResponse=executeGet(API_V1_ADMIN_APPLICATION_USERS+applicationUser
.getUsername());
ApplicationUser responseBody=getResponseBody(响应,ApplicationUser.class);
verifyResponseStatus(响应,HttpStatus.OK.value());
assertEquals(应用程序用户、响应库);
}
//失败的测试:
@试验
public void getUsersTest()引发异常{
当(applicationUserServiceMock.getAllUsers())。然后返回(applicationUsersList);
MockHttpServletResponse=executeGet(API_V1_ADMIN_APPLICATION_USERS);
List responseBody=getResponseBodyList(响应,ApplicationUser.class);
verifyResponseStatus(响应,HttpStatus.OK.value());
assertEquals(3,responseBody.size());//此断言通过
assertEquals(应用程序服务器列表、响应库);
//在最后一次assertEquals中失败。调试它后,我可以看到responseBody最终是一个LinkedHashMaps列表。
//我假设是因为我得到的是一个对象列表,而不是ApplicationUsers列表。
}
我需要做的是(至少作为第一种方法),让TypeReferenceListImpl返回T的实际类的列表类型,我将其作为参数类clazz传递。但我似乎无法基于类对象创建该特定类型的列表,以使用getClass()获取其类型。这是我采取的许多方法中的最后一种,但没有一种有效

有可能吗?还是有人有其他方法来解决这个问题

我试图创建一个通用方法来获取返回不同类型对象列表的所有控制器测试的响应体

堆栈跟踪是:

java.lang.AssertionError: expected:<[{
  "id" : 1001,
  "username" : "goku",
  "password" : null,
  "email" : "goku@dbz.com",
  "firstName" : "Goku",
  "lastName" : "Son",
  "lastLogin" : null,
  "authorities" : [ {
    "id" : 10,
    "name" : "ADMIN_ROLE"
  } ],
  "accountNonExpired" : true,
  "accountNonLocked" : true,
  "credentialsNonExpired" : true,
  "enabled" : true
}, {
  "id" : 1002,
  "username" : "gohan",
  "password" : null,
  "email" : "gohan@dbz.com",
  "firstName" : null,
  "lastName" : null,
  "lastLogin" : null,
  "authorities" : [ {
    "id" : null,
    "name" : "ROLE_USER"
  } ],
  "accountNonExpired" : true,
  "accountNonLocked" : true,
  "credentialsNonExpired" : true,
  "enabled" : true
}, {
  "id" : 1003,
  "username" : "goten",
  "password" : null,
  "email" : "goten@dbz.com",
  "firstName" : null,
  "lastName" : null,
  "lastLogin" : null,
  "authorities" : [ {
    "id" : null,
    "name" : "ROLE_USER"
  } ],
  "accountNonExpired" : true,
  "accountNonLocked" : true,
  "credentialsNonExpired" : true,
  "enabled" : true
}]> but was:<[{id=1001, username=goku, password=null, email=goku@dbz.com, firstName=Goku, lastName=Son, lastLogin=null, authorities=[{id=10, name=ADMIN_ROLE}], accountNonExpired=true, accountNonLocked=true, credentialsNonExpired=true, enabled=true}, {id=1002, username=gohan, password=null, email=gohan@dbz.com, firstName=null, lastName=null, lastLogin=null, authorities=[{id=null, name=ROLE_USER}], accountNonExpired=true, accountNonLocked=true, credentialsNonExpired=true, enabled=true}, {id=1003, username=goten, password=null, email=goten@dbz.com, firstName=null, lastName=null, lastLogin=null, authorities=[{id=null, name=ROLE_USER}], accountNonExpired=true, accountNonLocked=true, credentialsNonExpired=true, enabled=true}]>
    at org.junit.Assert.fail(Assert.java:88)
    at org.junit.Assert.failNotEquals(Assert.java:834)
    at org.junit.Assert.assertEquals(Assert.java:118)
    at org.junit.Assert.assertEquals(Assert.java:144)
    at com.nicobrest.kamehouse.admin.controller.ApplicationUserControllerTest.getUsersTest(ApplicationUserControllerTest.java:91)
    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$1.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.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.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    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:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.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:191)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:89)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
...
java.lang.AssertionError:应为:但为:
位于org.junit.Assert.fail(Assert.java:88)
位于org.junit.Assert.failNotEquals(Assert.java:834)
位于org.junit.Assert.assertEquals(Assert.java:118)
位于org.junit.Assert.assertEquals(Assert.java:144)
位于com.nicobrest.kamehouse.admin.controller.ApplicationUserControllerTest.getUsersTest(ApplicationUserControllerTest.java:91)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(未知源)
在sun.reflect.DelegatingMethodAccessorImpl.invoke处(未知源)
位于java.lang.reflect.Method.invoke(未知源)
位于org.junit.runners.model.FrameworkMethod$1.runReflectVeCall(FrameworkMethod.java:50)
位于org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
位于org.junit.runners.model.FrameworkMethod.invokeeexplosive(FrameworkMethod.java:47)
位于org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
位于org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
位于org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
位于org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
位于org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:239)
位于org.junit.rules.RunRules.evaluate(RunRules.java:20)
位于org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
位于org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
位于org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
位于org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
位于org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
位于org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
  protected static <T> List<T> getResponseBodyList(MockHttpServletResponse response, Class<T> clazz)
      throws JsonParseException, JsonMappingException, UnsupportedEncodingException, IOException,
      InstantiationException, IllegalAccessException {
    ObjectMapper mapper = new ObjectMapper();
    List<T> responseBody = mapper.readValue(response.getContentAsString(),
        mapper.getTypeFactory().constructCollectionType(List.class, clazz));
    return responseBody;
  }

  protected static <T> T getResponseBody(MockHttpServletResponse response, Class<T> clazz)
      throws JsonParseException, JsonMappingException, UnsupportedEncodingException, IOException {
    ObjectMapper mapper = new ObjectMapper();
    T responseBody = mapper.readValue(response.getContentAsString(),
        mapper.getTypeFactory().constructType(clazz));
    return responseBody;
  }
public <T> T readValue(String src,
          TypeReference valueTypeRef)
        throws IOException,
               JsonParseException,
               JsonMappingException
public String writeValueAsString(Object value)
                      throws JsonProcessingException