We know that we should always write unit tests for our code, and mock dependencies; but that isn’t always easy when we need to mock classes define as final
, or that contain final methods. This isn’t normally a problem when we’re only working with classes within our own libraries and applications, because we control whether they are final or not, and we can type-hint these dependencies to interfaces. However, when the dependencies that we use are from external libraries, we lose that control; and it can become harder to test our own classes if we do need to mock final classes adn they haven’t been built to interfaces.
Libraries like Mockery do provide a proxy approach to mocking final Classes, which works well, but with one major limitation.
In a compromise between mocking functionality and type safety,
Mockery does allow creating "proxy mocks" from classes marked
final, or from classes with methods marked final. This offers
all the usual mock object goodness but the resulting mock will
not inherit the class type of the object being mocked, i.e. it
will not pass any instanceof comparison.
Unfortunately, this limitation still causes problems when passing the mock to a method with type-hinted arguments to the class rather than to an interface if we need to Dependency-inject the mock; or if we don’t have much choice because the the final class wasn’t implementing an interface. Library writers take heed if you define any of your classes as final; always write them with an interface that can be type-hinted.
So is there any way we can create a test double that matches type-hinting when we need to pass it into the class that we’re testing? I’ve been looking at an alternative approach to mocking that does allow me to create a test double that extends a final class.
Continue reading →