Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds the ability to fake registered checks. #135

Merged
merged 4 commits into from
Nov 17, 2022

Conversation

lukeraymonddowning
Copy link
Contributor

Hey all!

Motivation

If you're a bit of a testing nut, like myself, you want to ensure that your health checks are registered correctly and throw the correct error status when in use. Up to now, this was not possible, because checks cannot be faked and will actually run as they would in production.

Implementation

To support this feature, I went down a similar route to Event::fake in Laravel. That is to say, we swap out the underlying Health instance with a FakeHealth instance that is able to take fake responses and use them for given health checks.

Here is a basic example:

it('has an error if the database is not available', function () {
  Health::fake([
    DatabaseCheck::class => new Result(Status::failed())
  ]);

  $this->get('/health')->assertStatus(503);
});

Advanced usage

There are occasions where it is necessary to have more control over the check. For example, imagine we want to override the shouldRun functionality, which by default defers to the original check. To satisfy this requirement, you may use the FakeCheck::result method.

it('has an error if the database is not available', function () {
  Health::fake([
    PingCheck::class => FakeCheck::result(new Result(Status::ok()), true)
  ]);

  $this->get('/health')->assertOk();
});

In the above example, we might imagine that in the testing environment, the check would not run because ::shouldRun returns false. We can force it to run by passing true as the second parameter to FakeCheck::result.

Let's imagine another example, where we use multiple DatabaseCheck instances to check multiple connections. What if each connection should return a different result in the test? No problem, we can pass a Closure to Health::fake:

Health::fake([
    DatabaseCheck::class => fn (DatabaseCheck $check) => $check->getName() === 'MySQL'
          ? new Result(Status::crashed())
          : new Result(Status::warning());
]);

I hope you find this as valuable as I will. Thanks for all the hard work you continue to do for the Laravel community!

Kind Regards,
Luke

@freekmurze
Copy link
Member

Thanks for this quality PR @lukeraymonddowning 👍

Could you take a look at the failing tests?

Could you also add some documentation on how to use the fake?

@lukeraymonddowning
Copy link
Contributor Author

lukeraymonddowning commented Nov 17, 2022

@freekmurze documentation added and tests fixed (I think at least, the workflow hasn't run again yet).

@freekmurze freekmurze merged commit 1d45c2d into spatie:main Nov 17, 2022
@freekmurze
Copy link
Member

Quality PR, thanks Luke!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants