Simulación de sincronización con implementaciones reales

El problema de sincronización aparece cada vez que se discuten las estrategias de prueba. Básicamente, debido a la carga adicional que crean los mokas para los desarrolladores y también los riesgos de que los mooks se desvíen de las dependencias reales.

Entonces, ¿de qué manera es más barato para nosotros garantizar la sincronización de mokas con implementaciones reales?

Para la sincronización, podemos escribir una prueba que realice las mismas comprobaciones contra mok y la implementación real.

Se parece a esto (escribo sin DI, pero con DI es más simple y más correcto):

public abstract class AbstractValidOrderDaoTest(){ Dao dao; public abstract arrange(); @Test public void whenValidOrderInDb_thenReturnValidOrder(){ arrange(); Order order = dao.retrieve(); assertNotNull(order); assertNotNull(order.getCustomerName()); //    } } public class ValidOrderDaoTest extends AbstractOrderDaoTest(){ @Override public void arrange(){ dao = new FakeValidOrderDao(); } } public class OrderDaoTest extends AbstractOrderDaoTest(){ @Override public void arrange(){ dao = new RealOrderDao(new ValidOrderDataSource(url, user, pwd)); } } 

OrderDaoTest funciona contra un objeto real con una simulación subyacente o dependencia real, y ValidOrderDaoTest funciona contra una simulación.

Si ValidOrderDataSource es una base de datos real, OrderDaoTest estará en un paquete separado y se ejecutará como parte de las pruebas de integración, que pueden bloquearse ocasionalmente al actualizar la base de datos, por ejemplo. Esto no debería interferir con CI \ CD.

Si ValidOrderDataSource es una base de datos simulada, OrderDaoTest se ejecutará junto con el resto de las pruebas unitarias.

Dado que la sincronización simulada implica probar una clase real, entonces para
la clase real tendrá que incursionar en sus dependencias subyacentes. Además, la adicción a Mok subyacente debe comportarse de acuerdo con el escenario del Mok suprayacente. En nuestro caso, esto
ValidOrderDataSource.

Si lo piensa, tiene sentido: cualquier afirmación sobre el comportamiento de las clases más altas implica implícitamente algún escenario en las subyacentes. Si el controlador devuelve algo del servicio, sería bueno que la base pudiera proporcionarlo.

Por el contrario, las clases altas a menudo viven con ideas poco realistas sobre las clases bajas, por lo que no está mal eliminar guiones innecesarios.

La recursividad sugiere que para sincronizar el simulacro de nivel superior, debe comenzar la sincronización de todos los simulacros subyacentes hasta dependencias externas.

Esto hace que la especificación del sistema sea aún más transparente, ya que los escenarios más generales y abstractos dependen de otros más privados.

También tenga en cuenta que hay mokas que no necesitan ser sincronizados. Es decir no tenemos una implementación tan real que deba probarse de forma cruzada. Esto se aplica a los principales escenarios de error. EmptyResultException_Datasource p. Ej. Esto reduce en gran medida la cantidad de pruebas cruzadas necesarias.

Ciertamente, la sincronización es necesaria para dependencias externas reales, como colas, servicios externos, bases de datos, especialmente con respecto a los datos que toman y devuelven.

Si el servicio externo cambia repentinamente, lo que a menudo se encuentra en la etapa de desarrollo, no tenemos forma de verificar su comportamiento si no escribimos una prueba de sincronización.

En términos de intensidad laboral. En sí mismo, ya tenemos una prueba de clase real con algunas dependencias simuladas arbitrarias. En comparación con las pruebas no sincronizadas, necesitamos hacer algunas cosas.

  • resaltar actuar y afirmar en una prueba abstracta
  • hacer una prueba específica para moka
  • arregla las dependencias simuladas en una prueba de clase real
  • si lo desea, complete recursivamente y repita todo el camino hasta dependencias externas.

Source: https://habr.com/ru/post/474964/


All Articles