Acceptance testing a PHP application that uses Notify
We needed a way of mocking the Notify API in our acceptance testing
Here at dxw, as we’ve blogged about before, we’re big fans of GOV.UK Notify. It’s a great service for sending emails, SMS and letters via a simple API request.
We’ve developed a number of PHP applications that use Notify via their PHP client. These applications have generally used Notify for messages that weren’t time-critical, so we’ve handled the Notify interactions via pushing the relevant data to a background queue, and then using that queue to generate requests to Notify. That’s meant our acceptance tests haven’t needed to mock the Notify API, as we only have to test that the appropriate data is getting pushed to the queue.
However, we recently started working on an application that uses Notify to send users the link they need to authenticate with the app. In this case, the Notify request is made synchronously, as we need to tell the user straight away if Notify hasn’t been able to send the email (e.g. if it’s experiencing downtime). Otherwise, a user could be left waiting for an email that’s never going to arrive.
Therefore, we needed a way of mocking the Notify API in our acceptance testing, so we can check that the application informs the user if it gets an error response from Notify, and also to confirm that the requests we were sending to the Notify API contained the appropriate data.
Fortunately, the Notify client provides a way for pointing requests to somewhere other than the production Notify API, via it’s `baseUrl` parameter:
That means you can inject a mock server’s URL, make assertions about the requests that the Notify client is making to it, and also mock responses to test that your application behaves correctly if it doesn’t get the expected successful response.
We did that in our tests, using Codeception as the testing framework, along with its Phiremock extension to mock the server and make assertions about the requests made to it. That worked well, but we realised we’d written a host of Notify-specific test assertions that we could extract and re-use. So that’s what we’ve done!
We’ve put together a Codeception module that extends the default Phiremock one, which allows you to make all the standard Phiremock assertions, plus a host of Notify-specific ones.
You can install it via composer:
composer require --dev dxw/codeception-notify-module
Set up the Phiremock extension in your codeception.yml, as you would normally:
Then enable and configure the module in your test suite’s config:
This config is the same as for the existing Phiremock module, so if you’re using that you should be able to just drop this in its place.
Then you can just start using the module’s methods to test the requests that are being made to your mock Notify server via the Notify PHP client, and to mock the responses e.g.
$I->expectEmailRequestWithSuccessResponse()
to provide a successful response to your next request to send an email, or
$I->expectEmailRequestWithFailureResponse()
to provide a 40x failure. You optionally specify the failure code and message provided as well.
You can also check the number of email requests made:
$I->seeNotifyReceivedEmailRequests(5)
And who they were sent to:
$I->getRecipientEmailAddresses()
to return an array of the recipients, or:
$I->seeLastEmailWasSentTo('address@domain.com')
to assert who the last recipient was.
Of course, all the existing Phiremock module methods are available too.
Currently, the module only covers email requests to Notify, but that could change in the future. You can find it here on GitHub. Feel free to open PRs, issues etc, and let us know if you find it useful!