Add discriminated union serialization tests - #2260
Conversation
Tests both request-side (params → map) and response-side (JSON → object) serialization for discriminated unions, covering standalone and inline variants. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
There was a problem hiding this comment.
Pull request overview
Adds a new unit test suite to validate the “discriminated union” serialization/deserialization patterns used in stripe-java, covering request-side params-to-map conversion via ApiRequestParamsConverter and response-side JSON-to-model parsing via ApiResource.GSON.
Changes:
- Introduces
DiscriminatedUnionSerializationTestwith request-side coverage for standalone (object-typed) and inline (parent-level discriminator + nested typed params) union shapes. - Adds response-side deserialization coverage for the same standalone and inline union shapes.
Suppressed comments (2)
src/test/java/com/stripe/net/DiscriminatedUnionSerializationTest.java:237
- The inline-union request serialization test doesn't assert that the non-selected variant field is omitted. Adding an explicit check helps ensure only the chosen variant is serialized.
Map<String, Object> map = converter.convert(params);
assertEquals("bank", map.get("type"));
Map<String, Object> bankMap = (Map<String, Object>) map.get("bank");
assertEquals("110000000", bankMap.get("routing_number"));
assertEquals("000123456789", bankMap.get("account_number"));
src/test/java/com/stripe/net/DiscriminatedUnionSerializationTest.java:267
- The inline-union response deserialization test should also assert that the non-selected variant (
bank) is null. Otherwise, a regression that populates both variants would still pass.
assertEquals("card", entity.type);
assertEquals("4242424242424242", entity.card.number);
assertEquals(Long.valueOf(12L), entity.card.expMonth);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| assertEquals("sunset", container.name); | ||
| assertEquals("rgb", container.color.model); | ||
| assertEquals(Long.valueOf(255L), container.color.r); | ||
| assertEquals(Long.valueOf(128L), container.color.g); | ||
| assertEquals(Long.valueOf(0L), container.color.b); |
There was a problem hiding this comment.
Added — the RGB deserialization test now asserts h/s/v are null, and the card deserialization test asserts bank is null.
| Map<String, Object> map = converter.convert(params); | ||
| assertEquals("card", map.get("type")); | ||
|
|
||
| Map<String, Object> cardMap = (Map<String, Object>) map.get("card"); | ||
| assertEquals("4242424242424242", cardMap.get("number")); | ||
| assertEquals(12L, cardMap.get("exp_month")); |
There was a problem hiding this comment.
Added — the card serialization test now asserts that bank is absent from the output map.
Assert that when one variant is selected, the other variant fields/structs remain null in both serialization and deserialization tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
…ar/discriminated-unions
Restructure the response-side test fixtures from a flat TestColorEntity class (holding all variant fields) to a proper class hierarchy: TestColorEntity (base) -> TestRgbColorEntity / TestHsvColorEntity. Add a TestColorTypeAdapterFactory that dispatches deserialization to the correct subclass based on the `model` discriminator field, mirroring how the codegen will emit TypeAdapterFactory-based dispatch for real DUs. Update assertions to use instanceof checks and typed casts rather than checking for null fields on a flat class. Add a second test covering the HSV variant path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Committed-By-Agent: claude
Why?
Validates that the discriminated union serialization design works correctly in stripe-java before codegen produces these patterns. Exercises both request-side (
ApiRequestParamsConverterserialization) and response-side (Gson polymorphic deserialization via TypeAdapterFactory).What?
DiscriminatedUnionSerializationTestwith 7 tests covering:Object-typed field on parent params holding variant class instances, each with a fixed discriminator initializer. VerifiesApiRequestParamsConverter.convert()produces correct nested map structure.Stringfield + typed variant params fields on parent. Verifies non-selected variant is null in output.TestColorEntity) with only discriminator field + variant subclasses extending it. CustomTestColorTypeAdapterFactorydispatches on discriminator value to correct subclass. Verifiesinstanceofand typed field access.