La burla falla con ‘No se pudo cargar el simulacro… la clase ya existe’ cuando se ejecuta con –code-coverage

2 minutos de lectura

Avatar de usuario de Daniel Becker
daniel becker

Estoy tratando de burlarme de una clase para phpunit. La unidad PHP falla con el error Could not load mock ... class already exists. Esta es la única prueba que estoy ejecutando, por lo que no puede ser el caso de que la clase ya se haya burlado.

Cualquier sugerencia sería apreciada.

Aquí está el caso de error:

namespace Tests\Feature;

use Tests\TestCase;

class DeactivateACSTest extends TestCase
{
    public function testDeactivateAcs()
    {
        $deviceController = \Mockery::mock('overload:App\Http\Controllers\Cloud\DeviceController');
        $deviceController
            ->shouldReceive('deactivateACS')
            ->andReturn('hilfehilfehilfe');

        $devCon = new \App\Http\Controllers\Cloud\DeviceController();
        $this->assertEquals('hilfehilfehilfe', $devCon->deactivateACS());
    }
}

Al ejecutarlo sin --code-coverage funciona:

[13:10:15] vagrant@homestead [~/Code/ekp] $ phpunit --filter DeactivateACS
PHPUnit 6.5.10 by Sebastian Bergmann and contributors.


 ==> Tests\Feature\DeactivateACSTest              ✓

Time: 1.08 seconds, Memory: 16.00MB

OK (1 test, 3 assertions)

Sin embargo, al ejecutarlo con --code-coverage falla:

[13:10:23] vagrant@homestead [~/Code/ekp] $ phpunit --coverage-html coverage --coverage-text=code_coverage.txt --filter DeactivateACSTest
PHPUnit 6.5.10 by Sebastian Bergmann and contributors.


  ==> Tests\Feature\DeactivateACSTest              ⚈

Time: 5.79 seconds, Memory: 44.00MB

There was 1 error:

1) Tests\Feature\DeactivateACSTest::testDeactivateAcs
Mockery\Exception\RuntimeException: Could not load mock \App\Http\Controllers\Cloud\DeviceController, class already exists

/home/vagrant/Code/ekp/vendor/mockery/mockery/library/Mockery/Container.php:220
/home/vagrant/Code/ekp/vendor/mockery/mockery/library/Mockery.php:116
/home/vagrant/Code/ekp/tests/Feature/DeactivateACSTest.php:11

ERRORS!
Tests: 1, Assertions: 0, Errors: 1.

Generating code coverage report in HTML format ... done

  • el mismo problema como lo solucionaste?

    – ultimátum

    21 de noviembre de 2018 a las 15:27

Debe agregar estas anotaciones antes de las funciones que se burlan de esta clase.

/**
 * @runInSeparateProcess
 * @preserveGlobalState disabled
 */

Como referencia, puede consultar la documentación de phpunit.

https://phpunit.de/manual/current/en/appendixes.annotations.html#appendixes.annotations.runInSeparateProcess

https://phpunit.de/manual/current/en/appendixes.annotations.html#appendixes.annotations.preserveGlobalState

  • No funciona en phpunit 7.4.3 y Mockery 1.2.2. Todavía da la Mockery\Exception\RuntimeException: Could not load mock Service, class already exists error.

    – Juha Untinen

    10 de abril de 2019 a las 10:15

  • ¡Gran truco! Esto funcionó perfectamente con PHPUnit 9.5 y Mockery 1.4 para una clase de prueba en la que estaba usando varias instancias simuladas con el overload prefijo. Al final terminé usando el @runTestsInSeparateProcesses anotación en toda la clase para simplificar. (En mi caso @preserveGlobalState en realidad no era necesario… YMMV).

    – Andrón

    3 de marzo de 2021 a las 22:11

  • Actualizar… resulta que esa clase de prueba en particular podría ejecutarse sin @preserveGlobalState disabledpero tuve que agregarlo al comentario de la clase para que todo el conjunto de pruebas se ejecutara correctamente.

    – Andrón

    4 de marzo de 2021 a las 13:53


Avatar de usuario de Vivek G
Vivek G.

Me encontré con el mismo problema y lo solucioné así:

  1. Había otra prueba en mis pruebas unitarias (no prueba de burla) que tenía require_once en el archivo PHP que tenía la clase de la que me estaba burlando. He eliminado esa línea.
  2. he añadido processIsolation="true" en conjunto de pruebas

¿Ha sido útil esta solución?