[ https://issues.apache.org/jira/browse/BEAM-9000?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Tomo Suzuki updated BEAM-9000: ------------------------------ Description: As of now, there are many tests that assert on {{toString()}} of objects. {code:java} CounterUpdate result = testObject.transform(monitoringInfo); assertEquals( "{cumulative=true, integer={highBits=0, lowBits=0}, " + "nameAndKind={kind=SUM, " + "name=transformedValue-ElementCount}}", result.toString()); {code} This style is prone to unnecessary maintenance of the test code when upgrading dependencies. Dependencies may change the internal ordering of fields and trivial change in {{toString()}}. In BEAM-8695, where I tried to upgrade google-http-client, there are many comparison failure due to this {{toString}} assertions. They are subclasses of \{{com.google.api.client.json.GenericJson}}. Several options to enhance these assertions. h1. Option 1: Assertion using Map Leveraging the fact that GenericJson is a subclass of AbstractMap<String, Object>, the assertion can be written as {code:java} ImmutableMap<String, Object> expected = ImmutableMap.of("cumulative", true, "integer", ImmutableMap.of("highBits", 0, "lowBits", 0), "nameAndKind", ImmutableMap.of("kind", "SUM", "name", "transformedValue-ElementCount")); assertEquals(expected, (Map<String, Object>)result); {code} h1. Option 2: Create assertEqualsOnJson Leveraging the fact that instance of GenericJson can be instantiated through JSON, the assertion can be written as {code:java} assertEqualsOnJson( "{\"cumulative\":true, \"integer\":{\"highBits\":0, \"lowBits\":0}, " + "\"nameAndKind\":{\"kind\":\"SUM\", " + "\"name\":\"transformedValue-ElementCount\"}}", result); {code} {{assertEqualsOnJson}} is implemented as below. The following field and methods should go to shared test utility class (sdks/testing?) {code:java} private static final JacksonFactory jacksonFactory = JacksonFactory.getDefaultInstance(); public static <T extends GenericJson> void assertEqualsOnJson(String expectedJsonText, T actual) { CounterUpdate expected = parse(expectedJsonText, CounterUpdate.class); assertEquals(expected, actual); } public static <T extends GenericJson> T parse(String text, Class<T> clazz) { try { JsonParser parser = jacksonFactory.createJsonParser(text); return parser.parse(clazz); } catch (IOException ex) { throw new IllegalArgumentException("Could not parse the text as " + clazz, ex); } } {code} was: As of now, there are many tests that assert on {{toString()}} of objects. {code:java} CounterUpdate result = testObject.transform(monitoringInfo); assertEquals( "{cumulative=true, integer={highBits=0, lowBits=0}, " + "nameAndKind={kind=SUM, " + "name=transformedValue-ElementCount}}", result.toString()); {code} This style is prone to unnecessary maintenance of the test code when upgrading dependencies. Dependencies may change the internal ordering of fields and trivial change in {{toString()}}. In BEAM-8695, where I tried to upgrade google-http-client, there are many comparison failure due to this {{toString}} assertions. Several options to enhance these assertions. h1. Option 1: Assertion using Map {code:java} ImmutableMap<String, Object> expected = ImmutableMap.of("cumulative", true, "integer", ImmutableMap.of("highBits", 0, "lowBits", 0), "nameAndKind", ImmutableMap.of("kind", "SUM", "name", "transformedValue-ElementCount")); assertEquals(expected, (Map<String, Object>)result); {code} h1. Option 2: Create assertEqualsOnJson {code:java} assertEqualsOnJson( "{\"cumulative\":true, \"integer\":{\"highBits\":0, \"lowBits\":0}, " + "\"nameAndKind\":{\"kind\":\"SUM\", " + "\"name\":\"transformedValue-ElementCount\"}}", result); {code} The following field and methods should go to shared test utility class (sdks/testing?) {code:java} private static final JacksonFactory jacksonFactory = JacksonFactory.getDefaultInstance(); public static <T extends GenericJson> void assertEqualsOnJson(String expectedJsonText, T actual) { CounterUpdate expected = parse(expectedJsonText, CounterUpdate.class); assertEquals(expected, actual); } public static <T extends GenericJson> T parse(String text, Class<T> clazz) { try { JsonParser parser = jacksonFactory.createJsonParser(text); return parser.parse(clazz); } catch (IOException ex) { throw new IllegalArgumentException("Could not parse the text as " + clazz, ex); } } {code} > Java Test Assertions without toString for GenericJson subclasses > ---------------------------------------------------------------- > > Key: BEAM-9000 > URL: https://issues.apache.org/jira/browse/BEAM-9000 > Project: Beam > Issue Type: Improvement > Components: testing > Reporter: Tomo Suzuki > Assignee: Tomo Suzuki > Priority: Minor > > As of now, there are many tests that assert on {{toString()}} of objects. > {code:java} > CounterUpdate result = testObject.transform(monitoringInfo); > assertEquals( > "{cumulative=true, integer={highBits=0, lowBits=0}, " > + "nameAndKind={kind=SUM, " > + "name=transformedValue-ElementCount}}", > result.toString()); > {code} > This style is prone to unnecessary maintenance of the test code when > upgrading dependencies. Dependencies may change the internal ordering of > fields and trivial change in {{toString()}}. In BEAM-8695, where I tried to > upgrade google-http-client, there are many comparison failure due to this > {{toString}} assertions. > They are subclasses of \{{com.google.api.client.json.GenericJson}}. > Several options to enhance these assertions. > h1. Option 1: Assertion using Map > Leveraging the fact that GenericJson is a subclass of AbstractMap<String, > Object>, the assertion can be written as > {code:java} > ImmutableMap<String, Object> expected = ImmutableMap.of("cumulative", > true, > "integer", ImmutableMap.of("highBits", 0, "lowBits", 0), > "nameAndKind", ImmutableMap.of("kind", "SUM", "name", > "transformedValue-ElementCount")); > assertEquals(expected, (Map<String, Object>)result); > {code} > h1. Option 2: Create assertEqualsOnJson > Leveraging the fact that instance of GenericJson can be instantiated through > JSON, the assertion can be written as > {code:java} > assertEqualsOnJson( > "{\"cumulative\":true, \"integer\":{\"highBits\":0, \"lowBits\":0}, " > + "\"nameAndKind\":{\"kind\":\"SUM\", " > + "\"name\":\"transformedValue-ElementCount\"}}", > result); > {code} > > {{assertEqualsOnJson}} is implemented as below. The following field and > methods should go to shared test utility class (sdks/testing?) > {code:java} > private static final JacksonFactory jacksonFactory = > JacksonFactory.getDefaultInstance(); > public static <T extends GenericJson> void assertEqualsOnJson(String > expectedJsonText, T actual) { > CounterUpdate expected = parse(expectedJsonText, CounterUpdate.class); > assertEquals(expected, actual); > } > public static <T extends GenericJson> T parse(String text, Class<T> clazz) { > try { > JsonParser parser = jacksonFactory.createJsonParser(text); > return parser.parse(clazz); > } catch (IOException ex) { > throw new IllegalArgumentException("Could not parse the text as " + > clazz, ex); > } > } > {code} -- This message was sent by Atlassian Jira (v8.3.4#803005)