Cuando me encontré por primera vez escribiendo pruebas para un microservicio, cuya API se implementó de acuerdo con el protocolo JSON-RPC, me di cuenta de que construir controles de calidad para elementos json es mucho más exigente de lo que pensaba antes.
El siguiente es un ejemplo simple.
Se recibió una respuesta del servicio:
{ "result": 12, "id": 46929734, "jsonrpc": "2.0" }
Lo que necesitas verificar:
- La respuesta contiene un elemento jsonrpc y su valor es 2.0
- La respuesta contiene un elemento id y su valor es igual a un elemento similar pasado en la solicitud, por el momento digamos que es 46929734
La respuesta contiene el elemento
"resultado" y su valor es
12Cómo verificar esto usando Java + TestNG + Gson:
Assert.assertTrue(response.has("result")); Assert.assertTrue(response.has("jsonrpc")); Assert.assertTrue(response.has("id")); Assert.assertTrue(response.get("result").isJsonPrimitive()); Assert.assertTrue(response.get("jsonrpc").isJsonPrimitive()); Assert.assertTrue(response.get("id").isJsonPrimitive()); Assert.assertEquals(response.get("result").getAsInt(), 12); Assert.assertEquals(response.get("jsonrpc").getAsString(), "2.0"); Assert.assertEquals(response.get("id").getAsInt(), 46929734);
En este momento, la pregunta "¿Por qué hay tantas afirmaciones?" Puede comenzar a formarse en la mente. Sí, de hecho, al realizar la prueba, solo le interesa el grupo de las últimas tres afirmaciones, comprueban los valores json de los elementos en la respuesta y, si pasan, la respuesta cumple con las expectativas. Pero, ¿qué pasa si la prueba falla? Considere varias razones posibles para la caída de tal prueba:
- Respuesta ->
{ "result": 12, "id": 46929734, "jsonrpc": "1.0" }
Error de TestNG -> java.lang.AssertionError: esperado [2.0] pero encontrado [1.0]
Esperaron "2.0" , obtuvieron "1.0" , aquí todo está claro.
- Respuesta ->
{ "result": 12, "id": 46929734, "jsonrpc": {} }
Error de TestNG -> java.lang.UnsupportedOperationException: JsonObject
Intentaron analizar un elemento como una cadena, que se recibió de forma absolutamente inesperada en la respuesta como un objeto.
- Respuesta ->
{ "result": 12, "id": 46929734 }
Error de TestNG -> java.lang.NullPointerException
Intentamos analizar un elemento que no está en la respuesta como una cadena.
Con el primer ejemplo, todo está bien. El error es comprensible, los valores reales y esperados son visibles de inmediato. Pero el segundo y el tercer ejemplo no pueden presumir de esto. Tal caída le toma al probador tiempo para analizar la causa. Debitar un error tan superficial es difícil. Llevará tiempo comprender qué elemento en particular intentó analizar la prueba, qué método intentó analizar y cómo se veía este elemento en la respuesta. Es posible que incluso deba reiniciar la prueba localmente, simplemente porque puede ser más rápido que recopilar toda la información necesaria de los registros del ensamblaje de prueba.
Tal cantidad de cheques, la necesidad de escribirlos y apoyarlos en un estado actualizado, me molestó mucho, así que creé una biblioteca separada en la que recopilé todos los cheques necesarios, en mi opinión, para elementos json. El mismo nivel de cobertura y detalle que requería el json anterior usando la biblioteca se logra en tres líneas, en lugar de nueve.
Gassert.verifyInteger(response, "result", 12); Gassert.verifyString(response, "jsonrpc", "2.0"); Gassert.verifyInteger(response, "id", 46929734);
La biblioteca implementa métodos para verificar:
- elementos de todos los tipos primitivos, anidados y no, con comprobación de valor y sin
- JsonObject, anidado y no, con comprobación de valor y sin
- JsonArray, anidado y no, con y sin comprobación de valor
- Elementos JsonNull anidados y no
- tipos de elementos dentro de una matriz
- el contenido de la matriz de elementos esperada
- dimensiones de la matriz
- dimensiones del objeto
En todos los niveles de verificación, se implementan errores más detallados en relación con los que TestNG proporciona de forma predeterminada.
Considere nuevamente las posibles causas de la caída de la prueba:
- Respuesta ->
{ "result": 12, "id": 46929734, "jsonrpc": "1.0" }
Error de Gassert -> java.lang.AssertionError: error de verificación del elemento [jsonrpc]. esperado [2.0] pero encontrado [1.0]
- Respuesta ->
{ "result": 12, "id": 46929734, "jsonrpc": {} }
Error de Gassert -> java.lang.AssertionError: El elemento [jsonrpc] no es un JsonPrimitive. no esperaba encontrar [verdadero] pero encontró [falso]
- Respuesta ->
{ "result": 12, "id": 46929734 }
Error de Gassert -> java.lang.AssertionError: Json no contiene el elemento: [jsonrpc]. no esperaba encontrar [verdadero] pero encontró [falso]
Además, la mayoría de los métodos de verificación están sobrecargados con un parámetro de cadena adicional, que en caso de una caída de aserción se agregará al texto del error mostrado. Esta característica se puede utilizar, por ejemplo, para mostrar el cuerpo completo de una respuesta o solicitud + respuesta por error.
La biblioteca está en el repositorio público de github, y también se agregó al repositorio maven.
MavenGithubAPIDocs