Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Have setup method run only once

I have:

1. IntegrationTestCase extends TestCase  
2. UnitTestCase extends TestCase
3. AcceptanceTestCase extends TestCase  

In these I have quite a lot of non-static methods which are used in a lot of tests. All of my Test classes extend one of these 3 classes.

Now in a lot of Test classes I have a setUp method which preps the data and services needed and assigns them to class variables:

class SomeTestClass extends IntegrationTestCase
{
    private $foo;

    public function setUp()
    {
        parent::setUp();

        $bar = $this->createBar(...);
        $this->foo = new Foo($bar);
    }

    public function testA() { $this->foo...; }  
    public function testB() { $this->foo...; }
}

Problem is setUp is ran for each test defeating what I wanted to do and if what setUp method does takes a long time this is multiplied by the number of test methods.

Using public function __construct(...) { parent::__construct(..); ... } creates a problem because now lower level methods and classes from Laravel are not available.

like image 433
Sterling Duchess Avatar asked Apr 03 '17 13:04

Sterling Duchess


1 Answers

For the next person running into this issue:

I had the problem that I wanted to migrate the database before running my tests but I didn't want the database to be migrated after each single test because the execution time would be way too high.

The solution for me was using a static property to check if the database was already migrated:

class SolutionTest extends TestCase
{
    protected static $wasSetup = false;

    protected function setUp()
    {
        parent::setUp();

        if ( ! static::$wasSetup) {
            $this->artisan('doctrine:schema:drop', [
                '--force' => true
            ]);

            $this->artisan('doctrine:schema:create');

            static::$wasSetup = true;
        }
    }
}
like image 182
Saman Hosseini Avatar answered Sep 23 '22 06:09

Saman Hosseini