Trying to help test this: https://gist.github.com/Vercoutere/c002cfb0040ddb04bf3d
I can't actually run this, but this is generally how I would test what you have without changing any of your code. It doesn't look quite as bad when you remove all the comments in the test :)
I've only provided an example of one specific code path, but the rest would follow a similar approach.
The test definitely has some complexity, which you might use to inform your design decisions. Most of the complexity comes
from global access to the Eloquent queries, and through the use of service location through the Route and App facades
to reach out and grab dependencies instead of passing them in.
All in all, it's pretty neat that you can still test this with confidence despite that, because Laravel does a pretty good job of making it easy to swap service located dependencies.
Changes you could make to simplify the test...
-
Register a
TenantMiddlewarebinding in the IOC container so you can control how it is built. This would let you pass in an instance ofTenantas a dependency, which you can use to make the static queries against. You could pass in a stub in your tests and avoid having to integrate against the database this way. PHP would happily let you do$tenants->getByDomain($domain)even thoughgetByDomainis a static method, pretty convenient for this sort of thing honestly. -
Pass in the
Contextas a dependency to the middleware as well instead of resolving it inline. Easier to pass the spy in this way. -
Use
$request->route('domain')instead ofRoute::input('domain')(for 'tld' and 'subdomain' as well) so you can pass in a stub for the$requestinstead of relying on stubbing through the facade.
These are just ideas and not things you definitely need to do, but worth considering. I don't subscribe to the idea that your goal when designing code should be to make testing as simple as possible, and have definitely seen it introduce unnecessary complexity. In this case though, these are probably pretty good changes to consider.
Hope that helps!