Mantenerse OO y verificable mientras trabaja con una base de datos

16

¿Cuáles son algunas estrategias de OOP para trabajar con una base de datos pero hacer que la unidad sea comprobable? Digamos que tengo una clase de usuario y mi entorno de producción funciona contra MySQL. Veo un par de enfoques posibles, que se muestran aquí usando PHP:

  1. Pase un $ data_source con interfaces para load()y save(), para abstraer el origen de datos del backend. Al realizar la prueba, pase un almacén de datos diferente.

    $ usuario = nuevo usuario ($ mysql_data_source);
    $ usuario-> carga ('bob');
    $ usuario-> setNickname ('Robby');
    $ usuario-> guardar ();
    
  2. Use una fábrica que acceda a la base de datos y pase la fila de resultados al constructor del Usuario. Al realizar la prueba, genere manualmente el parámetro $ row o simule el objeto en UserFactory :: $ data_source. (¿Cómo puedo guardar los cambios en el registro?)

    class UserFactory {
        static $data_source;
    
        public static function fetch( $username ) {
            $row = self::$data_source->get( [params] );
    
            $user = new User( $row );
            return $user;
        }
    }
    

Tengo patrones de diseño y código limpio aquí a mi lado, pero estoy luchando por encontrar conceptos aplicables.

Annika Backstrom
fuente

Respuestas:

11

Entonces, lo que desea elegir son los patrones de arquitectura de aplicaciones empresariales de Martin Fowlers (también proporciona un catálogo en su sitio web aquí ).

En él describe varios patrones para abstraer el acceso a datos. El primer enfoque que describe es Active Record . Su segundo enfoque es similar a Table Data Gateway .

Un enfoque aún mejor es usar un O / RM para eliminar la necesidad de escribir a mano el código de acceso a datos. No he usado PHP desde que estábamos preocupados por Y2K, pero wikipedia tiene una lista de opciones para usted . Sin embargo, no sé si son buenos. Sin embargo, puedo decirle algunas cosas que debe buscar en un O / RM:

  • Ignorancia de persistencia : el O / RM no debe obligar a sus objetos comerciales a derivar de una interfaz / clase específica para participar en la estrategia de acceso a datos.
  • Asignación de relaciones : debe poder asignar relaciones entre sus objetos (un cliente tiene pedidos, los pedidos tienen líneas de pedido, las líneas de pedido tienen un producto, etc.)
  • Mapeo jerárquico : debería poder mapear jerarquías de clase a la base de datos.
  • Soporte de sintaxis / criterios de consulta : debe poder crear una consulta en tiempo de ejecución en términos de sus objetos, no en términos de la base de datos, y el O / RM debe traducir y ejecutar la consulta en la base de datos. Puntos extra si la consulta es una cadena fuertemente tipada en lugar de una cadena.

Hay otros factores a considerar, pero esos son algunos de los más importantes. Espero que esto ayude.

Michael Brown
fuente
6

En mi humilde opinión, depende de lo que desee probar, si desea probar la unidad de su lógica de negocio, debe bloquear / burlar ( Martin Fowler ) su acceso a datos, por lo que su primera sugerencia es un buen comienzo. Esta pregunta de stackoverflow da un buen ejemplo de C # (intenté encontrar algunas muestras de PHP pero no pude encontrar ninguna).

Si desea probar el acceso a los datos en sí mismo, ya no se llama prueba unitaria sino prueba de integración. Lea aquí para obtener orientación general, esta pregunta de stackoverflow también tiene algunos enlaces interesantes.

Si desea probar la lógica del procedimiento almacenado en su base de datos, mire xUnit TestPattern

Espero que esto ayude

KeesDijk
fuente
2

Esta no es necesariamente una respuesta útil de inmediato, pero si está realmente preocupado por la capacidad de prueba de la base de datos, debe investigar cómo se hace en Ruby on Rails. Hasta donde yo sé, nadie ha cubierto el tema mejor o más intuitivamente.

Adam Crossland
fuente
2
Ruby on Rails implementa el patrón Active Record por defecto. También podría proporcionar un enlace: en.wikipedia.org/wiki/Active_record_pattern
Spoike
0

Le recomiendo que consulte la solución de Symfony Framework para este tipo de problema. Symfony es un framework php OO con pruebas funcionales.

Aquí hay un enlace , usaron algo como lo que estás pensando.

Guiman
fuente