mtedone / podam

PODAM - POjo DAta Mocker
https://mtedone.github.io/podam
MIT License
326 stars 749 forks source link

Wrapper field issue: Error working with OpenApi generated JsonNullable fields #289

Closed randeepbydesign closed 3 years ago

randeepbydesign commented 3 years ago

We updated our swagger code generation tool from swagger-codegen to the openapi code generator. It has introduced problems in several areas, including with mocking objects using podam. The reason is that the generator creates POJO which looks like this:

public class GeneratedClass {
   private JsonNullable<List<Info>> infoList = JsonNullable.<List<Info>>undefined();

   public info(List<Info> infoList) {
      this.infoList = JsonNullable.of(infoList);
   }

   public List<Info> getInfoList() { return info.orElse(null); }

   public void setInfoList(List<Info> infoList) {
      this.infoList = JsonNullable.<List<Info>>of(infoList);
   }

}

It causes a problem because when calling manufacturePojo, the code makes it way into PodamFactoryImpl.resolveCollectionValueWhenCollectionIsPojoAttribute and on line 1040 it attempts to assign the FieldValue, which is a Jsonnullable, to a collection.

JsonNullable is a Monad-type class that wraps the List, and because Podam uses the return type of the setter to determine the status of a list, a ClassCastException occurs. I think this could be an easy fix, but I'm not sure if it is a "bug" or if I am suppose to define a strategy for the case where the field type is JsonNullable. Can you advise?

I understand that this generated code is confusing and probably needlessly complicated, but for now we are restricted to this library to support a swagger format that is being provided.

daivanov commented 3 years ago

Hi,

In your code snippet getInfoList() uses info variable. But it is not defined anywhere.

public List<Info> getInfoList() { return info.orElse(null); }

if the code is supposed to look like this:

public List<Info> getInfoList() { return infoList.orElse(null); }

then it should return null and ClassCastException should not occur.

Could you please correct the POJO so it compiles so I can do a test to reproduce ClassCastException?

Thanks, Daniil

randeepbydesign commented 3 years ago

Hi, you are right! Here is the correct pojo:

public class GeneratedClass {
   private JsonNullable<List<Info>> infoList = JsonNullable.<List<Info>>undefined();

   public info(List<Info> infoList) {
      this.infoList = JsonNullable.of(infoList);
   }

   public List<Info> getInfoList() { 
      return infoList.orElse(null); 
   }

   public void setInfoList(List<Info> infoList) {
      this.infoList = JsonNullable.<List<Info>>of(infoList);
   }

}
randeepbydesign commented 3 years ago

I see what you are saying. If you look at the PodamUtils getFieldValue method, it gets the reflection Field of JsonNullable<List<?>>. Therefore the retValue is JsonNullable undefined. Were it calling the getInfoList method there would not be an issue. Let me know what you think.

You can see there is an annotation to surpress warning from casting... maybe an assertion is needed here to ensure the type is correct.

daivanov commented 3 years ago

Sorry for a delay. Fixed in podam-7.2.7 and later.

randeepbydesign commented 3 years ago

thank you so much