Getting PHPSpec to work with Laravel

I’ve recently started using PHPSpec to drive my testing efforts in a new Laravel project. The behaviour-driven approach makes a lot of sense to me but I am finding it a little difficult to master as the documentation hasn’t matured yet and as it’s not widely used (yet) there aren’t so many questions and answers to be found on the net.

One problem I ran into early on with my usage of PHPSpec with Laravel was that whilst my tests were passing, I was having an error thrown after the tests had passed in my CLI.

This error would look like:

# phpspec run
100% 4PHP Fatal error: Class 'Eloquent' not found in /path/to/app/models/Schedule.php on line 3

What struck me as weird was that the class being tested was app/Apes/ScheduleCalculator. Now this class used my Schedule model to query the database and the error being thrown referred to the Laravel model.

I wondered around in circles for quite a long time on this trying different approaches of trying to use Eloquent in the test class, in the model (it’s already being used there), and so on. My lack of familiarity with namespaces and OO architecture was definitely showing!

Now that I’ve worked out the fix, I think PHPSpec instantiates my classes in isolation from Laravel, resulting in this error (although this is probably not quite right as if it was wholly in isolation then my ScheduleCalculator class ‘use Schedule’ probably wouldn’t work!). Anyway, hopefully someone can provide me with some elucidation on this one.

The fix

This solution actually came thanks to Ben Constable via a question asked by Adamski on Stack Overflow. Ben Constable has created a package for using PHPSpec in Laravel which you’ll need to install first.

Then you need to edit your phpspec.yml file and include the following declaration:

extensions:
- PhpSpec\Laravel\Extension\LaravelExtension

This instantly fixes these Class ClassName not founderrors.

After fixing this error I quickly realised that you also need to tell PHPSpec what environment you’re using or you’ll encounter more errors. This can be done with the following phpspec.yml declaration.

laravel_extension:
testing_environment: your_local_env_name

I hope that helps someone avoid a potential coding rabbit hole, and would be delighted to hear any feedback or recommendations.

Comments