|
From: Marcus B. <ma...@wo...> - 2009-10-06 23:47:42
|
Hi...
Aaron Chilcott wrote:
> The problem is when it comes to mocking private methods. Using the
> example above: if the method /somethingElse/ is private, then it seems
> that it is no longer possible to mock the method e.g.
It works under the hood by overriding the real method. This will not
work for private methods. If you are going to override the method, then
make it protected.
> There is always a little glimmer of hope that let's me hold on to the
> possibility that this is not intended functionality and I don't have to
> re-write most of our test cases!
This is actually undefined behaviour :).
The idea of partial mocks is to automate a common pattern for inserting
dependencies - that of of overriding a factory method for testing
purposes. E.g...
class UserAgent {
// Code that uses Socket...
function createSocket($domain, $port) {
new Socket($domain, $port);
}
}
In the test...
class UserAgentWithMockSocket extends UserAgent {
public $socket;
function createSocket($domain, $port) {
return $this->socket;
}
}
class MyTest extends UnitTestCase {
function test...() {
$agent = new UserAgentWithMockSocket();
$agent->socket = new MockSocket();
...
$agent->fetch(...);
}
}
Note that all the other functionality of UserAgent is unchanged here.
The override is only used to inject a dependency. It's still tested as a
unit ("behaviour testing").
Modern techniques of dependency injection render this kind of trick
obsolete. Dependencies are likely passed in the constructor these days,
or as setters. See "Dependency injection", "Service Locator" and
"Registry" for alternate patterns. It would mean rewriting some code,
but it should actually be that onerous.
Using the partial mocks to test individual methods is likely to be
brittle in the face of refactoring. I'm guessing here, but if the
classes are that complicated that you have to test them in pieces, then
you probably want to break them up into smaller classes. A sign that
this is the case is usually a lot of private methods and few public ones.
You don't strictly need to rewrite all your tests, if you can get away
with using protected access instead of private, but I think you will
want to. Right now you might be over testing a little, and is it
possible that the tests are difficult to read through being over technical?
I'd have to see some real code to be sure. Can you post any?
> Thanks for your time
> Aaron
>
yours, Marcus
|