Reputation: 3583
I want to mock a method in the same class that I am testing.
ClassA {
function hardToTest($arg) {
// difficult to test code
}
function underTest() {
return $this->hardToTest('foo');
}
}
I was thinking that I could use reflection to do this, but maybe it is just a sign that I should move hardToTest
into another object.
Upvotes: 26
Views: 20510
Reputation: 58454
What exactly is the reason what method is hard to test ?
If the method is protected, and you really really want to test it, then you can just extend your ClassA and make the hardToTest($arg)
public.
The bottom line is that you shouldn't modify the class only because you need to write unittest for it. And in general, the private
and protected
methods should not be tested - you should test only the public interface.
Upvotes: -1
Reputation: 36562
This test will succeed if underTest()
passes 'foo'
to hardToTest()
. This is known as a partial mock in PHPUnit's documentation because you are mocking only some of the methods.
ClassATest {
function testUnderTest() {
$mock = $this->getMock('ClassA', ['hardToTest']);
$mock->expects($this->once())
->method('hardToTest')
->with('foo');
$mock->underTest();
}
}
I agree with your instincts that this need may be a code smell telling you that this class is doing too much.
PHPUnit 5.4+
Since getMock()
was deprecated in 5.4, use getMockBuilder()
instead:.
$mock = $this->getMockBuilder('ClassA')
->setMethods(['hardToTest']) // onlyMethods in 8.4+
->getMock();
Upvotes: 25
Reputation: 3583
What I resorted was creating a sub class of my system under test with the relevant method stubbed out.
Upvotes: 0