Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何对Mockito模拟的对象使用Gson TypeAdapter?_Java_Unit Testing_Gson_Mockito - Fatal编程技术网

Java 如何对Mockito模拟的对象使用Gson TypeAdapter?

Java 如何对Mockito模拟的对象使用Gson TypeAdapter?,java,unit-testing,gson,mockito,Java,Unit Testing,Gson,Mockito,我想模拟通过TypeAdapter传入Gson的对象,如下所示: @RunWith(MockitoJUnitRunner.class) public class SceneExporterTest { @Test public void testWriter() { List<SceneObject> sceneObjects = mockSceneObjects(); Gson gson = new GsonBuilder().registerTypeAdapte

我想模拟通过TypeAdapter传入Gson的对象,如下所示:

@RunWith(MockitoJUnitRunner.class)
public class SceneExporterTest {

@Test
public void testWriter() {
    List<SceneObject> sceneObjects = mockSceneObjects();
    Gson gson = new GsonBuilder().registerTypeAdapter(SceneObject.class, new SceneExporter()).create();

    String s = gson.toJson(sceneObjects); //This method ends up with an exception.
}

private List<SceneObject> mockSceneObjects() {
    List<SceneObject> sceneObjects = new LinkedList<>();
    for (int i = 0; i < 50; i++) {
        sceneObjects.add(mockSceneObject(i));
    }
    return sceneObjects;
}

private SceneObject mockSceneObject(int i) {
    SceneObject sceneObject = mock(SceneObject.class);
    //...
    return sceneObject;
}

}

场景对象是相当重的对象,我不想在测试中正常地实例化它。那么有没有可能只是嘲笑它?我也不想使用Spies。

以这种方式创建的
SceneObject
实例的运行时类型:
mock(SceneObject.class)
SceneObject$MockitoMock$

以以下方式创建的
SceneObject
实例的运行时类型:
new SceneObject()
SceneObject

因此,当Gson的
TypeAdapterRuntimeTypeWrapper
在其上下文中为模拟对象查找注册的
TypeAdapter
时,它将找不到,因为您的
SceneExporter
已针对
SceneObject.class
注册

这实际上是说,模拟的
SceneObject
不是类型的
SceneObject
(它实际上是
SceneObject
的一个子类),因此Gson将找不到您的定制类型适配器

如果您这样声明
Gson

Gson gson = new GsonBuilder().registerTypeAdapter(mock(SceneObject.class).getClass(), new SceneExporter()).create();
。。。然后它将找到您的定制类型适配器,但注册看起来“关闭”,不是吗?这感觉像是一个只测试的专业

如果你真的必须模拟
场景对象
,那么我认为你需要注册一个,但是如果你这么做只是为了支持这个测试用例,那感觉就像是一个只测试的限制流到了“主”源代码树中。因此,最简单的解决方案可能是:

  • 创建
    SceneObject的真实实例
  • 使用Mockito
    Spy
    删除在
    SceneExporter
java.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: com.editor.api.scene.objects.SceneObject. Forgot to register a type adapter?
Gson gson = new GsonBuilder().registerTypeAdapter(mock(SceneObject.class).getClass(), new SceneExporter()).create();