Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing a Laravel 5 route with an exists rule via Codeception

I'm writing tests for my Laravel application using the Codeception library. I'm using the Laravel5 module, and have it configured with cleanup which means that all tests will run inside a database transaction, so that my testing database doesn't get filled with test data.

One of the endpoints I'm testing has the following validation rules set against it via Form Requests:

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

The test that I've written to POST to this endpoint is as follows:

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);
}

This test always fails. After investigating, I can see that it fails because the request is failing validation due to the exists:users,id rule. If I change the Codeception settings to not execute tests inside a transaction, Laravel's validator can successfully see the existence of the two user's that I created at the start of my test and the test passes.

So, my question is, is there any way that I can maintain the behaviour of wrapping each of my tests in a database transaction, and have Laravel's validator be able to see the records that I create in my tests?

like image 506
John Dorean Avatar asked Oct 12 '15 16:10

John Dorean


1 Answers

The problem is, that if the transaction is not commited, the original data in the database tables is not affected. So within the transaction, you create two users, but there is no commit statement that would persist that to your database. Hence the laravel validation rule 'exists' cannot find them ( that rule makes a database request to find particular user_id ).

So in your case the users have to exist before testing. I would recommend to use Migrations instead. Resetting Database after each test

Create your tables with database migrations and seeds and roll them back after tests have finished.

like image 135
shock_gone_wild Avatar answered Oct 23 '22 02:10

shock_gone_wild