Pregunta

Tengo un proyecto en el que estoy usando código generado por .nettiers como mi DAL.

Por el momento, mis pruebas consisten en configurar físicamente los datos de prueba en la base de datos para cada prueba, luego permitir que los objetos nettiers lleguen a la base de datos y regresen según sea necesario.

Obviamente, esto no es particularmente eficiente y hasta ahora mis 250 pruebas impares tardan unos 10 minutos en ejecutarse, por lo que he estado buscando agregar burlas a mis pruebas.

Si bien estoy bastante seguro de que entiendo los conceptos de burlarse de las llamadas a la base de datos, tengo problemas para aplicarlo a los nettiers en particular, ya que está bastante fuertemente acoplado a la base de datos.

Uno de los métodos que quiero probar se ve así (reducido ligeramente por razones de brevedad):

public class InterfaceManagerService
{
    public DataDocument SaveDataDocument(DataDocument entity)
    {
        var lookupEntity = DataRepository.DataDocumentProvider.GetByDocumentId(entity.DocumentId);
        if (lookupEntity == null)
        {
            File fileEntity = new File();
            fileEntity.Name = entity.Name;

            var savedFileEntity = DataRepository.FileProvider.Save(fileEntity);

            entity.FileId = savedFileEntity.FileId;

            var savedEntity = DataRepository.DataDocumentProvider.Save(entity);

            return (savedEntity);
        }             
    }
}

Actualmente, estoy usando una versión de prueba de Typemock, ya que parece hacer lo que se requiere, pero estoy abierto a cualquier alternativa, particularmente las de código abierto.

El primer problema que encontré fue si debería crear una instancia simulada de InterfaceManagerService, o del DataRepository, o de las Entidades mismas (las entidades nettiers tienen una interfaz que podría ser útil).

El segundo problema es cómo crear el objeto falso que se devolverá, ya que los nettiers colocan un montón de propiedades adicionales en las entidades que darían como resultado pruebas grandes y difíciles de manejar si creo una instancia falsa de cada objeto que espero.

Supongo que, en última instancia, estoy buscando alguna dirección sobre la mejor manera de escribir pruebas unitarias para métodos que utilizan métodos de repositorio de datos de Nettiers, pero para evitar acceder a la base de datos, ya que actualmente no parece haber mucho al respecto en Internet. .

¿Fue útil?

Solución

Voy a dar algunas sugerencias derivadas de mi experiencia personal.Si bien es posible que estos no aborden todas sus inquietudes, espero que al menos le sean de alguna ayuda.

  • Rhino Mocks es un framework de burla bastante conocido.Si está buscando una alternativa a Typemock, se la sugiero.

  • En cuanto a si burlarse de InterfaceManagerService o DataRepository, diría que depende de lo que esté intentando probar.¿Quieres probar InterfaceManagerService?Entonces querrás crear objetos simulados para DataRepository.FileProvider y DataRepository.DataDocumentProvider.Si aún no está familiarizado con el concepto de "inyección de dependencia", investíguelo;parece que deberías aplicar alguna inyección de dependencia a tu clase InterfaceManagerService (suponiendo que quieras realizar una prueba unitaria).

    Si desea realizar una prueba unitaria de código que consume InterfaceManagerService, simplemente simule InterfaceManagerService.

...Cómo crear el objeto falso que se va a devolver, ya que Nettiers pone un montón de propiedades adicionales en las entidades que darían como resultado pruebas grandes y transeantes si creo una instancia falsa de cada objeto que espero.

  • Escribir una prueba unitaria única es fácil.Escribir muchas pruebas unitarias para cubrir todos los escenarios que necesita cubrir y hacerlo de una manera eficiente que no dé como resultado que se duplique mucho código a lo largo de las pruebas unitarias es difícil, especialmente cuando las entradas y salidas del método que se está probando son complejos.

    Para esto no tengo mucha orientación, aparte de decir que mi enfoque personal es tratar de consolidar la lógica de inicialización de pruebas y la lógica de verificación de pruebas para evitar mucha duplicación de código, pero al mismo tiempo trato de evitar hacer El código de prueba unitaria en sí es tan complicado que resulta difícil de entender y propenso a errores.

    En general, creo que termino dividiendo la lógica de prueba en 3 categorías:insumos/inicialización, expectativas y resultados/verificación.Descubrí que poner la lógica en estas 3 categorías me resultó útil para poder consolidar el código común en las pruebas unitarias.

    Los defensores acérrimos del desarrollo basado en pruebas probablemente dirían que luchar para producir un conjunto limpio de código de prueba unitaria es una indicación de una falla de diseño en la aplicación.No voy a estar en desacuerdo con eso, pero diré que, desafortunadamente, los proyectos en los que he estado involucrado generalmente no han producido una base de código de prueba unitaria que fuera simple y completamente completa.Las pruebas unitarias simples generalmente no exploraban escenarios problemáticos, y las pruebas unitarias integrales generalmente requerían mucha lógica de configuración de prueba.

Otros consejos

Uso Typemock y me gusta mucho. Es realmente fácil burlarse de las partes internas de una clase. Lo que busco hacer es anular la clase DataRepository y hacer que Typemock devuelva un conjunto de resultados esperado a mi componente que lo está consumiendo, para asegurarse de que el componente funcione como se esperaba.

Pero en realidad, depende de lo que esté probando. Si está probando el servicio, fingue el repositorio de datos y devuelva los resultados esperados. Si está probando el repositorio, fingir las partes internas que consume el repositorio. Entonces, una buena idea es fingir las referencias externas al componente que está probando, en mi humilde opinión.

Hth.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top