When you're writing tests that involve third-party services, it's useful to mock out those services, so you're not constantly hitting live APIs in your tests.
Not only does this keep your tests running faster, it also saves you from incurring upstream charges or filling a sandbox account with test data.
That being said, if you only interact with mocks in your tests, how do you know your code actually works with the live API? How do you detect possible API drift over time?
In our normal feature tests we block all API calls with Http::preventStrayRequests()
.
But then we have an extra folder tests/External
, where we place the subset of our tests that should hit a live API.
Our normal phpunit.xml
config file does not include the external tests, so when we just run phpunit
it will not run those tests by default.
We then have a phpunit-external.xml
config file, which is pretty much identical to our main config, except it only defines the External
test suite:
<testsuites>
<testsuite name="External">
<directory>./tests/External</directory>
</testsuite>
</testsuites>
Now, we can have two different test scripts in our composer.json
, which we call depending on whether we want to run external tests our not:
{
"scripts": {
"test": [
"phpunit"
],
"test-external": [
"phpunit --configuration=phpunit-external.xml"
]
}
}
We have achieved the goal of fast tests and still being able to detect API drift.
Here to help,
Joel
P.S. Have you seen Ash Allen's excellent book on Laravel APIs?