I have an AuthorizationUpdater
service, with an implementation based on Doctrine ORM. While I finished the production code, and have some tests, I was forced out of my usual TDD cycle by not knowing how to write these two:
- testWhenDatabaseReadFails_exceptionIsThrown (to test this code)
- testWhenDatabaseWriteFails_exceptionIsThrown (to test this code)
The Doctrine implementation of AuthorizationUpdater
take a Doctine EntityManager
in its constructor, which it uses to do a read and a write. These two tests are supposed to test that when either of these EntityManager methods throws a Doctine ORMException
, it is caught by the service and converted to a domain exception.
My test is an integration test that gets the EntityManager
to use from a factory.
Creating a simple fake via the PHPUnit mock API (getMock('className')->method('updateStuff')->willThrow(new SomeExcetion)
) does not seem nice in this case. The service uses the EntityManager
before the method the exception gets thrown from, so mocking out everything is not an option. This leaves creating some complex fake of EntityManager
and partially mocking it (just the method that should throw an exception). The later requires providing the real constructor arguments, which my test actually does not have access to, as this responsibility lies in another package. Hence both approach are not satisfactory, and leave me preferring to have this ORMException
catching behaviour to be not tested.
Is there a nice way to write the tests I'm after? Being able to monkey-patch the relevant method on the EntityManager
instance would be prefect, though that'd require the runkit extension.
I'm using PHP 7, and might be able to switch to PHP 7.1 if needed.In case you're curious, the code is on GitHub, with the relevant tests residing at the end of DoctrineAuthorizationUpdaterTest
.