5
votes

I'm trying to use Codeception to run my Laravel 4 unit tests.

Running a test for a simple class with no dependencies works fine. But when I instantiate a model which depends on Eloquent, I get this fatal error:

PHP Fatal error: Class 'Eloquent' not found in /var/www/project/app/models/Role.php on line 4

Unit test:

<?php
use Codeception\Util\Stub;
class TestModel extends \Codeception\TestCase\Test 
{
  public function testExample()
  {
    $role = new Role;
    $role->name = 'superuser';
    $this->assertEquals('superuser', $role->name);
  }
}

Model:

<?php
class Role extends Eloquent
{
  public function users()
  {
    return $this->belongsToMany('User');
  }
}

Project structure:

I'm running vendor/bin/codecept run unit from the project root, with this file structure:

/project
  codeception.yml
  /vendor/bin/codecept
  /app
    /tests
      unit.suite.yml
      /unit
         ExampleTest.php
    /models
       Role.php
                ...etc

What am I doing wrong?

6
I dont know about codeception especially, but with PHPUnit, you need to at least bootstrap the class autoloading. Perhaps it's the same with Codeception.fideloper
I know this is crazy late but after you install the composer package. You type in the root directory of the site. "vendor/bin/codecept _bootstrap" and that will generate the file for you.John

6 Answers

8
votes

By looking at the Codeception L4 sample app, I was able to see how to bootstrap the autoload to resolve this issue, by adding these lines to project/app/tests/_boostrap.php:

include __DIR__.'/../../vendor/autoload.php';
$app = require_once __DIR__.'/../../bootstrap/start.php';
\Codeception\Util\Autoload::registerSuffix('Page', __DIR__.DIRECTORY_SEPARATOR.'_pages');

Edit: when upgrading from Laravel 4.0 to 4.1, it is also necessary to add an extra line:

$app->boot();
3
votes

I'm probably late to the party, but if you don't need the codecept stuff. You should be extending laravel's implementation of PHPUnit_Framework_TestCase called just TestCase. Like this:

class TestModel extends TestCase {
}
3
votes

The answer to this question is a little outdated now. With Laravel 5 I got the same error (Class 'Eloquent' not found...) and solved it by copying the code from Laravels base TestCase.php file. This file is used for testing within the Laravel framework (NOT using codeception).

To fix the 'Eloquent not found' error, add the following lines to project/tests/unit/_bootstrap.php

<?php
$app = require __DIR__.'/../../bootstrap/app.php';
$app->make('Illuminate\Contracts\Console\Kernel')->bootstrap();

Honestly I'm not sure why it works, but it does! I'll edit if I figure out why or someone comments.

0
votes

The Eloquent class cannot be found when you are running your unit tests.

Try adding use Illuminate\Database\Eloquent\Model as Eloquent; to Role.php.

0
votes

You can go to TestCase class and override method refreshApplication (add method to TestCase) with adding auth or some:

protected function refreshApplication()
{
    $this->app = $this->createApplication();

    $this->client = $this->createClient();

    $this->app->setRequestForConsoleEnvironment();

    $this->app->boot();

    // authenticate your user here, when app is ready
    $user = new User(array('username' => 'John', 'password' => 'test'));
    $this->be($user);
}
0
votes

I solved a similar problem with Laravel 4 and Codeception by adding the following lines to _bootstrap.php

$app = require __DIR__.'/../../bootstrap/start.php'; $app->boot();

Hope this helps a fellow googler!