Pregunta

Revisé las diversas preguntas sobre pruebas unitarias pero no encuentro ninguna que responda específicamente a esta pregunta.

Tengo varias clases de PHP que contienen funciones similares a esta:

    static function _setSuspended($Suspended, $UserID)
    {
        try {
            $con = Propel::getConnection();

            $c1 = new Criteria();
            $c1->add(DomainsPeer::USERID,$UserID);

            $update = new Criteria();
            $update->add(DomainsPeer::SUSPENDED,$Suspended);

            BasePeer::doUpdate($c1, $update, $con);

            return true;
        } catch(PropelException $e) {
            return $e->getMessage();
        }
    }

Estoy usando Propel como mi ORM.He leído varios temas de pruebas unitarias que hablan sobre la creación de 'Simulacros' y 'Stubs' y demás, pero no he podido encontrar nada que indique específicamente cómo probar una función como la anterior.

Mi pensamiento es algo como:Necesito probar la función anterior, así que me gustaría llamarla.Pero si lo llamo, usa Propel como ORM y de acuerdo con los principios de prueba unitaria debo aislar cada función por sí misma.

Simplemente no veo una manera de hacer eso.¿Que me estoy perdiendo aqui?

¿Fue útil?

Solución

He encontrado que burlarse de la ORM no me da ninguna confianza porque la configuración ORM nunca se probó. ORM también tienen porciones de acción en un efectos de la distancia que pueden dar una falsa confianza con pruebas de unidad. Burlándose del controlador de base de datos o la prestación de un suplente base de datos en memoria me da mucho mayor confianza de mi código es correcto y es casi tan duro como burlándose del ORM.

SQLite es una gran base de datos en memoria para las pruebas unitarias. Está en la lista de bases de datos PDO compatible. (DOP es el motor de base de datos Propel 1.3.) Si no desea utilizar una base de datos en memoria, es posible que pueda encontrar un simulacro de DOP ya escrito.

Otros consejos

Esta es una respuesta genérica en la que no estoy familiarizado con Propel en absoluto y sólo un poco más familiarizados con PHP. La respuesta básica es que se utiliza la inyección de dependencias. En lugar de referirse directamente a su ORM, se crea una envoltura alrededor de ella, y luego inyectar el envoltorio en su clase / función para utilizar realmente. Para hacer las pruebas unitarias, a continuación, crear una versión simulada o falsa de la envoltura que no interfaz para el ORM pero en cambio le permite configurar las respuestas de la envoltura para sus invocaciones de métodos. Esto le permite factorizar el ORM cuando la unidad de pruebas de sus funciones.

Yo estaba tratando de abordar el mismo problema, mientras que la construcción de una PHPUnit Plugin para Symfony . Terminé acercarse a ella de manera similar a de Django ensayo del bastidor -. utilizar una base de datos / conexión independiente, y destruir y reconstruir antes de cada prueba

Me di cuenta de que también era capaz de salirse con la única reconstrucción de la base de datos de prueba antes de la primera prueba en una prueba de funcionamiento (o si una prueba instruye explícitamente a); antes de que las otras pruebas, sólo se borran todos los datos para acelerar las cosas un poco.

He estado leyendo el blog Misko de Hevery acerca de las pruebas mucho últimamente. Cubre esta situación; que había necesidad de utilizar DI (inyección de dependencias).

Estoy luchando a mí mismo con esto un poco, así, y también uso de propulsión.

Por un lado, se podría mover el método de "suspender" a la clase "objeto" en lugar de los pares. Para esta función particular, de todos modos, no es necesario utilizar los métodos estáticos para lograrlo. Su API podría ser:

MyObjectPeer::retrieveByPK(1)->suspend();

Esto sería comprobable a través de métodos normales de ensayo unidad.

Si es realmente la base de datos que necesita ser probado, entonces yo sepa lo que necesita en realidad tienen el DB involucrado en la prueba. Estoy usando ltree y Postgis mucho en mi proyecto actual y no puedo pensar en ninguna otra forma de ejecutar las pruebas unitarias para la lógica del modelo que depende de la base de datos distinta de incluirlo en mis pruebas.

Este es un ejemplo de una clase con dependencia estricta que no se puede probar por unidad.

Podríamos poder realizar la prueba con una conexión a otra base de datos, pero ya no es una prueba unitaria sino una prueba de integración.

La mejor alternativa en la que pienso es tener una clase QueryFactory que incluya todos los diferentes métodos que necesitas y luego podrás burlarte de ella.

Primero en primero creo una interfaz

interface iQueryFactory
{
    function firstFunction($argument);
    function secondFunction($argument, $argument2);
}

El QueryFactory con todas las solicitudes ORM que necesitamos

class QueryFactory implements iQueryFactory
{
    function firstFunction($argument) 
    {
        // ORM thing
    }

    function secondFunction($argument, $argument2)
    {
        // ORM stuff
    }
}

Existe la lógica empresarial con la inyección de la fábrica de consultas.

class BusinessLogic 
{
    protected $queryFactory;

    function __construct($queryFactoryInjection) 
    {
        $this->queryFactory= $queryFactoryInjection;
    }

    function yourFunctionInYourBusinessLogique($argument, $argument2) 
    {
        // business logique

        try {
            $this->queryFactory->secondFunction($argument, $argument2);
        } catch (\Exception $e) {
            // log
            // return thing
        }

        // return stuff
    }
}

La parte simulada, tenga en cuenta que no uso un marco simulado para mi ejemplo (por cierto, puede crear un configurador de respuestas)

class QueryFactoryMock implements iQueryFactory
{
    function firstFunction($argument) 
    {
        if (is_null($argument)) 
        {
            throw new \Exception("");
        } 
        else 
        {
            return "succes";
        }
    }

    function firstFunction($argument, $argument2) 
    { 
        // sutff  
    }
}

Luego, finalmente, las Pruebas Unitarias que prueban nuestra lógica de negocios con la implementación simulada.

class BusinessLogicTest extends PHPUnit_Framework_TestCase 
{
    public function setUp() 
    {
        require_once "BusinessLogic.php";
    }

    public function testFirstFunction_WhenInsertGoodName() 
    {
        $queryMockup = new QueryFactoryMock();
        $businessLogicObject = new BusinessLogic($queryMockup);
        $response = $businessLogicObject ->firstFunction("fabien");

        $this->assertEquals($response, "succes");
    }

    public function testFirstFunction_WhenInsetNull() 
    {
        $queryMockup = new QueryFactoryMock();
        $businessLogicObject = new BusinessLogic($queryMockup);
        $response = $businessLogicObject->firstFunction(null);

        $this->assertEquals($response, "fail");
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top