2016-08-10 27 views
9

Chciałbym użyć Laravel's Model Factory w niektórych testach PHPUnit. Jedyne, co chcę zrobić, to utworzyć instancję modelu bez zapisywania jej w bazie danych.Fabryka modeli Laravel bez połączenia z bazą danych

Dlaczego fabryka modeli wymaga połączenia z bazą danych? Testy te muszą przejść do środowiska CI bez skonfigurowanej bazy danych.

Po utworzeniu modelu ręcznie przez new App\Model($dataArray) testy przechodzą pomyślnie, a połączenie nie jest potrzebne.

Używam Model Factory w innych miejscach, dlatego chciałbym użyć go ponownie w tych testach, aby uniknąć powielania kodu.

Używam biblioteki MongoDB i jenssegers/laravel-mongodb, ale domyślam się, że nie ma to znaczenia - w czystym Wymownym i np. Baza danych MySQL, problem byłby taki sam.

testowy, który działa bez bazy danych:

class ModelTransformerTest extends TestCase 
{ 
    public function testTransformMinimalModelData() 
    { 
     $data = [ 
      '_id' => $faker->md5, 
      'email' => $faker->email, 
     ]; 

     $model = new App\Model($data); 
     // […]; 
    } 
} 

moim modelu Fabryce

$factory->defineAs(Model::class, 'base', function ($faker) { 
    return [ 
     '_id' => $faker->md5, 
     'email' => $faker->email, 
    ]; 
}); 

test, który potrzebuje połączenia z bazą danych:

class ModelTransformerTest extends TestCase 
{ 
    public function testTransformMinimalModelData() 
    { 
     $model = factory(App\Model::class, 'base')->make(); 
     // […]; 
    } 
} 

Pełna śledzenia stosu:

Error: Class 'MongoDB\Driver\Manager' not found 

app\vendor\mongodb\mongodb\src\Client.php:56 
app\vendor\jenssegers\mongodb\src\Jenssegers\Mongodb\Connection.php:147 
app\vendor\jenssegers\mongodb\src\Jenssegers\Mongodb\Connection.php:37 
app\vendor\jenssegers\mongodb\src\Jenssegers\Mongodb\MongodbServiceProvider.php:27 
app\vendor\illuminate\database\DatabaseManager.php:173 
app\vendor\illuminate\database\DatabaseManager.php:68 
app\vendor\illuminate\database\Eloquent\Model.php:3282 
app\vendor\illuminate\database\Eloquent\Model.php:3248 
app\vendor\jenssegers\mongodb\src\Jenssegers\Mongodb\Eloquent\Model.php:523 
app\vendor\jenssegers\mongodb\src\Jenssegers\Mongodb\Eloquent\Model.php:284 
app\vendor\illuminate\database\Eloquent\Model.php:443 
app\vendor\illuminate\database\Eloquent\Model.php:281 
app\vendor\illuminate\database\Eloquent\FactoryBuilder.php:142 
app\vendor\illuminate\database\Eloquent\Model.php:2286 
app\vendor\illuminate\database\Eloquent\FactoryBuilder.php:143 
app\vendor\illuminate\database\Eloquent\FactoryBuilder.php:106 
app\tests\phpunit\Transformers\ModelTransformerTest.php:25 
\php\pear\PHPUnit\TextUI\Command.php:176 
\php\pear\PHPUnit\TextUI\Command.php:129 
+0

Można używać SQLite do tego. Laravel oferuje opcję utworzenia SQLite DB w pamięci. Więc technicznie masz bazę danych, ale nie zapełni ona twojego MongoDB lub MySQL itp. Jak tylko testy się zakończą, DB jest usuwany z pamięci – user3425867

Odpowiedz

0

Nie sądzę, że jest to obecnie możliwe. Metoda make() wywołuje newModelInstance(), która próbuje ustawić połączenie z bazą danych.

Użytkownik może samemu przejrzeć numer source code.

0

Zwykle chodzę do stworzenia podobnego testu DB i uruchomienia wszystkich testów na tym DB.

Zapewnia to, że testowy typ bazy danych jest taki sam jak w przypadku produkcji i nie dotyka się produkcyjnej bazy danych w celu przeprowadzenia testów.

0

Czy próbujesz użyć DatabaseTransactions?

Na przykład

use Illuminate\Foundation\Testing\DatabaseTransactions; 
class ModelTransformerTest extends TestCase 
{ 
    use DatabaseTransactions; 
}