Тестирование маршрута Laravel 5 с помощью правила существования через Codeception

Я пишу тесты для своего приложения Laravel, используя библиотеку Codeception. Я использую модуль Laravel5 и настроил его с помощью cleanup, что означает, что все тесты будут выполняться внутри транзакции базы данных, так что моя тестовая база данных не будет заполнить тестовые данные.

Одна из конечных точек, которые я тестирую, имеет следующие правила проверки, установленные против нее через запросы формы:

public function rules()
{
    return ['user_id' => 'required|exists:users,id'];
}

Тест, который я написал POST для этой конечной точки, выглядит следующим образом:

public function store(ApiTester $I)
{
    // Create a couple of users
    $users = factory(\App\Models\User::class, 2)->create();

    $I->wantTo('ask someone to be my friend');
    $I->authenticateAs($users[0]);
    $I->sendPOST('users/' . $users[0]->id . '/friendships', [
        'user_id' => $users[1]->id
    ]);
    $I->seeResponseCodeIs(201);
}

Этот тест всегда терпит неудачу. После изучения я вижу, что он терпит неудачу, потому что запрос не проходит проверку из-за правила exists:users,id. Если я изменил настройки Codeception, чтобы не выполнять тесты внутри транзакции, валидатор Laravel может успешно увидеть существование двух пользователей, которые я создал в начале моего теста, и тест проходит.

Итак, мой вопрос заключается в том, можно ли каким-либо образом поддерживать поведение переноса каждого из моих тестов в транзакции базы данных и иметь ли валидатор Laravel возможность видеть записи, которые я создаю в своих тестах?

Ответ 1

Проблема заключается в том, что если транзакция не совершена, исходные данные в таблицах базы данных не затрагиваются. Таким образом, внутри транзакции вы создаете двух пользователей, но нет инструкции фиксации, которая будет сохраняться в вашей базе данных. Следовательно, правило валидации laravel "существует" не может их найти (это правило делает запрос базы данных на поиск определенного user_id).

Итак, в вашем случае пользователи должны существовать перед тестированием. Вместо этого я бы рекомендовал использовать Migrations. Сброс базы данных после каждого теста

Создайте свои таблицы с миграциями и семенами базы данных и откатите их после завершения тестов.

Ответ 2

Цитата:

$I->sendPOST('users/' . $users[0]->id . '/friendships', [
    'user_id' => $users[1]->id
]);

Почему вы отправляете $users[0]->id в URL-адрес запроса, а затем 'user_id' => $users[1]->id в параметрах?

Это может быть ваша проблема? Может ли это быть причиной того, что вы отказываетесь от проверки?