Using TestCase to aid in testing in Laravel

John Von Colln
2 min readApr 14, 2021

A mentor of mine told me about a way to “boot” things into your TestCase, that is, the base of all your tests — unless you have created your own from BaseTestCase. I knew this was what I was looking for, but totally forgot about how to do it. Anyways — full disclosure, this is more for me than anyone else, as is the rest of the garbage that I write. Maybe you’ll find it useful some how.

The problem I was faced was that I had just implemented a new way for our system to calculate shipping charges. Previously, we would let the shipping software write back the actual cost of the shipment for each order that was shipped via an api call. This has worked fine for a while, but there are a few problems with this approach:

  • Final order value could not be determined until the order has been shipped
  • Shopping cart shipping quotes sometimes differ from actual cost

So I decided that we really just need to calculate the shipping charges when the order is placed. The problem though is that we have a ton of tests that create orders and I don’t want to hit the EasyPost api on each test, for dozens and dozens of tests. Not only would that slow things down, but it would also be an undue burden on EasyPost and probably result in some rate limiting errors.

So I wanted to find a way to find an easy way to not dispatch the shipping calculation job, without having to add this code every time I created an order.

Bus::fake(CalculateOrderShippingCharges::class);

One thing that we could do, is in our TestCase class, we can hook into the setup() method, which gets executed when the test is being run. We have to be sure to add parent::setup to have TestCase’s base class execute what it needs to. Here’s what that might look like:

This would work, but what about when we actually want to test dispatching the job? Of course, we could do something like this:

(new CalculateOrderShippingCharges($order))->handle()

to avoid the job Bus. But I’d like things to be a little more obvious, so we’re going to make a trait that we can add to any test that will do the same thing.

There are two important pieces here. First the @before annotation and second, the afterApplicationCreated() method.

The @before annotation boots the code below it. The afterApplicationCreated() method can receive a callable function that gets executed at its lifecycle point.

Now, in my test file, I can just add this trait whenever I need it.

--

--

John Von Colln
0 Followers

Founder of PrintOps.com — a print on demand drop shipping company based in Nashville, TN. Working with PHP, Laravel and other stuff.