无法在Gson自定义反序列化器中初始化Android.Util.Pair

时间:2017-02-16 15:05:26

标签: java android json junit deserialization

我正在为我当前的应用程序中的数据模型创建custom deserializer,并且在尝试初始化Pair<>内的CustomDeserializer时遇到了一些问题。我从我的Json中恢复了我的项目A和B,它们很好并且从JsonObject正确初始化,但是当我想用它们创建new Pair<>(A,B)时,我得到了一个例外:

  

方法抛出'java.lang.RuntimeException'异常。无法评估android.util.Pair.toString()

我一直在寻找更多有同样问题的人,但我找不到任何关于此的提示,我不知道为什么我无法初始化deserializer内的项目。我正在junit测试中执行我的所有代码,所以也许是由它造成的,但我不知道为什么。以下是我deserializer的代码:

public class CustomSetDeserializer implements JsonDeserializer<ExerciseSet> {

   private List<Exercise> exerciseList;

   public CustomSetDeserializer(List<Exercise> exerciseList) {
      this.exerciseList = exerciseList;
   }

   @Override
   public ExerciseSet deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
      List<Pair<Exercise, Integer>> setExercises = new ArrayList<>();
      JsonArray exercisesJsonArray = json.getAsJsonObject().get("exercises").getAsJsonArray();
      for (JsonElement jsonElement : exercisesJsonArray) {
         String name = jsonElement.getAsJsonObject().get("name").getAsString();
         int reps = jsonElement.getAsJsonObject().get("reps").getAsInt();
         Exercise exercise = getExercise(name);
         setExercises.add(new Pair<>(exercise, reps));
      }
      int exercisesPerRound = json.getAsJsonObject().get("exercisesPerRound").getAsInt();
      int restBetweenRounds = json.getAsJsonObject().get("restBetweenRounds").getAsInt();
      ExerciseSet set;
      switch (exercisesPerRound) {
         case 3:
            //TODO TRISET  
            set = new SimpleSet(setExercises, restBetweenRounds);
            break;
         case 2:
            //TODO SUPERSET
            set = new SimpleSet(setExercises, restBetweenRounds);
            break;
         default:
            set = new SimpleSet(setExercises, restBetweenRounds);
            break;
      }
      return set;
   }

   private Exercise getExercise(String name){
      for (Exercise exercise : exerciseList) {
         if (!exercise.name().equals(name)) continue;
         return exercise;
      }
      throw new IllegalArgumentException("Wrong exercise name");
   }
}

这是我的测试:

 @Test
   public void read_set_json() {
      CustomSetDeserializer customSetDeserializer = new CustomSetDeserializer(exercises);
      Gson gson = new GsonBuilder().registerTypeAdapter(ExerciseSet.class, customSetDeserializer).enableComplexMapKeySerialization().create();
      ExerciseSet set = gson.fromJson(setExample, ExerciseSet.class);
      assertThat(set.exercises().get(0).first.equals(exercise), is(true));
      assertThat(set.exercises().get(0).second.equals(12), is(true));
      assertThat(set.rounds(), is(4));
      assertThat(set.restBetweenRound(), is(60L));
   }

如果我调试我的代码一切正常,但Pair<>永远不会被创建,所以我总是检索List个满空Pair<>

希望有人能够帮助我!

1 个答案:

答案 0 :(得分:1)

在你的Junit测试中,你不能引用android代码(android.util.Pair),因为这个测试是在你的本地jvm中执行的,并且没有这个类来初始化。

考虑使用Robolectric lib来模拟android类,或者在代码中抽象它们并且不要使用具体化(Android Framework类)并使用这个抽象并用Mockito模拟它们。