当前位置: 首页 > 知识库问答 >
问题:

如何对复杂的typeToken的正确配置进行单元测试?

邵弘致
2023-03-14

我有一些使用泛型和TypeTokens来反序列化JSON的服务代码。需要该服务来反序列化保持其泛型参数类型的复杂TypeToken。

<T extends IPolicy> TypeToken<PolicyWrapper<T>> makePolicyWrapperTypeToken(Class<T> policyClass) {
    TypeToken<T> policyTypeToken = TypeToken.of(policyClass);
    return new TypeToken<PolicyWrapper<T>>() {}
        .where(new TypeParameter<T>() {}, policyTypeToken);
  }
java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap 
cannot be cast to com.myStuff.IPolicy

看起来我在调试的时候是对的。toString()函数表明它知道它的泛型类型参数:

com.myStuff.PolicyWrapper<com.myStuff.PolicyImpl>

最后,我有一个单元测试。它通过,但不测试泛型类型参数。我测试了TypeToken的rawType(),得到了正确的类,但我不确定如何测试它的泛型类型。

@Test
 public void makePolicyWrapperTypeToken() throws NoSuchMethodException {

    TypeToken<?> wrapperToken = makePolicyWrapperTypeToken(PolicyImpl.class);
    assertEquals(wrapperToken.getRawType(), PolicyWrapper.class);

     //the getContent returns a list but it needs the generic type tested
     TypeToken<?> contentToken = wrapperToken.resolveType(PolicyWrapper.class.getMethod("getContent").getGenericReturnType());
     assertEquals(contentToken.getRawType(), List.class);

  }

共有1个答案

琴正初
2023-03-14

TypeToken似乎无法正常工作,因为我从GSON那里得到了一个类强制转换错误。java.lang.ClassCastException:com.google.gson.internal.LinkedTreeMap不能强制转换为com.mystuff.ipolicy

不是真的。在您的例子中,看起来Gson在反序列化时没有接收到足够的类型信息。LinkedTreemap是Gson内部映射实现,默认情况下,Gson用于反序列化具有任意结构的未知类型的对象。例如,如果泛型类参数化信息由于某种原因丢失/擦除,就可能发生这种情况。例如,private final List List; 可以由ProGuard之类的工具处理,因此它可能变成private final List List;除非使用-keepattributes签名--一般来说,它是合法的Java代码,但是Gson没有足够的类型信息,而是使用LinkedTreemap。当您试图将这样一个列表元素分配给IPolicy引用时,应该会得到这样的结果。另一个场景是typeToken.getRawType()而不是type.getToken():原始类型不包含参数化信息,因此new typeToken >(){}.getRawType() 只是list.class--仍然没有关于元素类型的信息,使Gson使用默认策略。

getContent返回一个列表,但它需要测试泛型类型

只需使用typeToken.getType(),它返回java.lang.reflect.type,这是所有类型的基接口。参数化泛型类型用parameterizedtype表示,与更一般的type不同,它提供了关于类型参数化的更多信息,而且这些信息也可以用类型标记构建。因此,以下断言为真:

// not really necessary, but just for the demonstration purposes:
assertTrue(contentToken.getType() instanceof ParameterizedType);
// this is enough:
assertEquals(new TypeToken<List<PolicyImpl>>() {}.getType(), contentToken.getType());
 类似资料:
  • 我正在尝试使用测试驱动设计方法编写一个应用程序--我对单元测试很陌生,所以我只是想知道测试正确输入和异常的正确方法是什么。 我有一个用于加载配置文件的类: null 另外,这3个测试是否都有try{}catch(){}语句?在第一个测试中,正确性是隐含的,在第二个和第三个测试中,我无论如何都在检查异常,所以异常对测试没有影响。

  • 问题内容: 如何在单元测试中测试 hashCode()函数? 问题答案: 每当我覆盖equals和hash代码时,我都会按照Joshua Bloch在“ Effective Java”第3章中的建议编写单元测试。我确保equals和hash代码是自反的,对称的和可传递的。我还确保“不等于”对所有数据成员均正常工作。 当我检查对equals的调用时,我还要确保hashCode的行为符合预期。像这样:

  • 问题内容: 我一直在学习AngularJS,并且在单元测试方面进展非常顺利,但是我遇到了一个棘手的问题。 假设我有一个简单的表格,例如: 如果我正在测试类似控制器的东西,我知道我会这样写(使用Jasmine + Karma): 但是我不知道我需要注入哪些服务,也没有运气在指南或文档中找到有关单元测试的文档。 一个单元如何在Angular中测试表单? 问题答案: 我不认为这是对此类内容进行单元测试的

  • 本文向大家介绍对Angular.js Controller如何进行单元测试,包括了对Angular.js Controller如何进行单元测试的使用技巧和注意事项,需要的朋友参考一下 一、写个简单的Angular App 在开始写测试之前,我们先写一个简单的计算App,它会计算两个数字之和。 代码如下: 二、简单说说里面涉及的一些基本概念: 创建一个 module 什么是angular.modul

  • 问题内容: 如您所知,异常情况下会引发异常。那么如何模拟这些异常呢?我觉得这是挑战。对于此类代码段: 有人有好主意吗? 问题答案: 其他答案已经解决了如何编写用于检查是否引发异常的单元测试的一般问题。但是我认为您的问题实际上是在询问如何获取代码以首先引发异常。 以您的代码为例。在简单的单元测试的环境中,很难在内部引发异常。问题是,为了使异常发生,代码(通常)需要在网络中断的计算机上运行。安排在单元

  • 在探索如何对Kafka流进行单元测试时,我遇到了,不幸的是,这个类似乎被版本(KAFKA-4408)破坏了 对于KTable的问题,是否有一个解决方案? 我看到了“mocked streams”项目,但首先它使用的是,而我使用的是,其次它是Scala,而我的测试是Java/Groovy。 这里的任何关于如何在不需要引导zookeeper/kafka的情况下对流进行单元测试的帮助都将非常棒。 注意: