laravel 5.8 отключить метод сохранения модели во время тестирования

#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 , если вы отлаживаете.