| 148 |
lars |
1 |
.. index::
|
|
|
2 |
single: Mocking; Final Classes/Methods
|
|
|
3 |
|
|
|
4 |
Dealing with Final Classes/Methods
|
|
|
5 |
==================================
|
|
|
6 |
|
|
|
7 |
One of the primary restrictions of mock objects in PHP, is that mocking
|
|
|
8 |
classes or methods marked final is hard. The final keyword prevents methods so
|
|
|
9 |
marked from being replaced in subclasses (subclassing is how mock objects can
|
|
|
10 |
inherit the type of the class or object being mocked).
|
|
|
11 |
|
|
|
12 |
The simplest solution is to implement an interface in your final class and
|
|
|
13 |
typehint against / mock this.
|
|
|
14 |
|
|
|
15 |
However this may not be possible in some third party libraries.
|
|
|
16 |
Mockery does allow creating "proxy mocks" from classes marked final, or from
|
|
|
17 |
classes with methods marked final. This offers all the usual mock object
|
|
|
18 |
goodness but the resulting mock will not inherit the class type of the object
|
|
|
19 |
being mocked, i.e. it will not pass any instanceof comparison. Methods marked
|
|
|
20 |
as final will be proxied to the original method, i.e., final methods can't be
|
|
|
21 |
mocked.
|
|
|
22 |
|
|
|
23 |
We can create a proxy mock by passing the instantiated object we wish to
|
|
|
24 |
mock into ``\Mockery::mock()``, i.e. Mockery will then generate a Proxy to the
|
|
|
25 |
real object and selectively intercept method calls for the purposes of setting
|
|
|
26 |
and meeting expectations.
|
|
|
27 |
|
|
|
28 |
See the :ref:`creating-test-doubles-partial-test-doubles` chapter, the subsection
|
|
|
29 |
about proxied partial test doubles.
|