#php #laravel-5.8
#php #laravel-5.8
Вопрос:
Я хочу протестировать службу, которая изменяет состояние модели.
это моя модель :
<?php
namespace AppModels;
use IlluminateDatabaseEloquentModel;
class Color extends Model
{
protected $table = 'color';
protected $connection = 'someconnection';
public $timestamps = false;
}
и это сервис :
<?php
namespace AppServices;
use AppModelsColor;
class ColorChanger
{
public function changeColor(Color $color): void
{
switch($color->name) {
case 'green':
$color->name = 'red';
break;
case 'red':
$color->name = 'orange';
break;
}
$color->save();
}
}
Я попытался сделать простой тест, подобный этому :
<?php
namespace TestsUnitServices;
use AppModelsColor;
use AppServicesColorChanger;
use TestsTestCase;
class ColorChangerTest extends TestCase
{
public function test_color_has_changed_from_green_to_red()
{
$color = new Color();
$color->name = 'green';
$colorChanger = new ColorChanger();
$colorChanger->changeColor($color);
$this->assertEquals('red', $color->name);
}
}
но когда я запускаю тест, он выдает ошибку, потому save
что метод пытается обновить базу данных.
Я нахожусь в тестовой среде, и база данных недоступна.
Я пробовал фабрики, я пытался издеваться над цветовой моделью, чтобы предотвратить save
метод подключения к базе данных, но тщетно.
В итоге я использовал шаблон репозитория, я ввожу его в сервис ColorChanger и имитирую его метод сохранения во время теста.
class ColorRepo
{
public function save(Color $color): bool
{
return $color->save();
}
class ColorChanger
{
private ColorRepo $colorRepo;
public function __construct(ColorRepo $colorRepo): void
{
$this->colorRepo = $colorRepo;
}
public function changeColor(Color $color): void
{
switch($color->name) {
case 'green':
$color->name = 'red';
break;
case 'red':
$color->name = 'orange';
break;
}
$this->colorRepo->save($color);
}
}
Нет ли другого простого способа отключить метод сохранения моделей? Потому что использование шаблона репозитория добавляет дополнительные коды, которые кажутся мне действительно слишком большими для этого простого случая.
Комментарии:
1.
changeColor(Color $color, $save = true)
, затемif ($save) { $color-save(); }
и просто сделайте$changeColor($color, false)
в своем тесте 🙂2. да, ваше предложение выглядит как самое простое, спасибо.
Ответ №1:
Я подумываю о создании class
вызываемого Mockable
или чего-то подобного, что выглядело бы так:
class Mockable {
public static $isDebug = false;
public static function save($repo, $entity) : void
{
if ($isDebug) $repo->save($entity);
}
}
и назовите его следующим образом
Mockable::save($this->colorRepo, $color);
конечно, вам нужно будет перейти $isDebug
на true
, если вы отлаживаете.