如何在 mockmvc 中将模拟对象作为 JSON 发送

2022-09-01 22:49:30

我想通过内容类型JSON的MockMvc在控制器中发送一个模拟对象。但是当我尝试序列化模拟时,错误是:

java.lang.UnsupportedOperationException: Expecting parameterized type, got interface org.mockito.internal.MockitoInvocationHandler.
 Are you missing the use of TypeToken idiom?

我的代码如下:

@Test
public void testSomething(){

    String xyz = "";
    Integer i = 10;
    SomeClass inst = mock(SomeClass.class, withSettings().serializable());
    when(inst.getProperty1()).then(xyz);
    when(inst.getProperty2()).then(i);

    Gson gson = new Gson();
    String json = gson.toJson(inst); // this is creating error

    this.mockmvc.perform(put("/someUrl/").contentType(MediaType.JSON).content(json)).andExpect(status().isOk());
}

有人能告诉我我错过了什么吗?


答案 1

我建议您创建一个存根,该存根返回 and 方法的已知值。根据实现方式,您可以直接创建它的实例,子类并重写某些方法,如果它是接口,则创建匿名内部类等。SomeClassgetProperty1()getProperty2()SomeClassnew

@Test
public void testSomething(){

    String xyz = "";
    Integer i = 10;

    // alt 1:
    SomeClass stub = new SomeClass(xyz, i);

    // alt 2: 
    SomeClass stub = new StubSomeClass(xyz, i); // StubSomeClass extends SomeClass

    // alt 3: 
    SomeClass stub = new SomeClass() {
         @Override
         String getProperty1() {
             return xyz;
         }
         @Override
         Integer getProperty2() {
             return i;
         }
    }

    Gson gson = new Gson();
    String json = gson.toJson(stub);

    this.mockmvc.perform(put("/someUrl/")
        .contentType(MediaType.APPLICATION_JSON).content(json))
        .andExpect(status().isOk());
}

答案 2

即使有可能,将模拟对象提交到JSON转换器也会假设一个专用于该操作的单元测试:模拟对象可能具有许多远远超出实际类的属性和方法,序列化可能导致一个非常奇怪的结果。

恕我直言,由于它是一个单元测试,您应该手动编写json序列化字符串。如果您需要控制Gson如何进行序列化,则可以进行其他测试