Take a look at setUpBeforeClass().For the one time tearDown you should use tearDownAfterClass();.Both this methods should be defined in your…
Stubbing Eloquent Relations for Faster Tests
When you’re trying to test methods on an Eloquent model, you often need to hit the database to really test your code.
But sometimes the functionality you’re testing doesn’t really depend on database features. Is there any way to test that stuff without hitting the database?
Testing against the database
Say we had
Songs and we wanted to test that we could calculate the total duration of an album.
Our test might look something like this:
A simple implementation of
$album->duration could look like this:
If we run this test everything will pass, but at least on my machine, it takes about ~90ms on average to run.
For tests that really need to hit the database for me to verify the behavior I’m trying to verify, I’m totally fine with that.
But in this case, we aren’t trying to test a specific set of query scopes, or verify that something is being saved, we just want to sum some numbers!
There must be another way!
When you eager load a relationship, using the
$album->songs property shorthand doesn’t perform a new query; instead it fetches the
Songs from a memoized property on the
We can pretend to eager load a relationship manually using the
Now we can get rid of the
DatabaseMigrations trait and use
make to build our
Album instead of
create, leaving us with a test that looks like this:
Running this test still passes, but this time it only takes about 3ms to finish! That’s thirty times faster.
Nothing is free
As with anything, there’s a cost to using this approach.
If we changed our implementation to sum the song durations in the database, our new test would fail:
So while the performance improvements are insane, they come at the cost of coupling us to a particular style of implementation, and make things a little less flexible to refactor.
Either way, it’s a cool trick to keep in mind if your test suite is starting to slow down, and often the benefits will outweigh the cost.