Reputation: 24077
I'm trying to unit test a class where one public method (method 1) uses another public method (method 2) of the same class within it. E.g.
class MyClass {
public function method1()
{
$var = $this->method2();
// Do stuff with var to get $answer
return $answer;
}
public function method2()
{
// Do complex workings out to get $var
return $var;
}
}
Now, method2
is already unit tested and I don't want to build up an argument for it to actually call it whilst testing method1
. I just want to mock up method2
and define in my test what would be returned. This is what I have:
function test_method1()
{
$myClass = new MyClass();
$mockedMyClass = Mockery::mock('MyClass');
$mockedMyClass->shouldReceive('method2')->once()->andReturn([1,2,3,4]); // mocked $var returned to be used in the rest of method1
$answer = $myClass->method1();
// Assertions
}
Clearly this doesn't work as the method being tested is in the same class as contains the method being mocked, so there's no way to pass in the mocked class as a dependency. What's the best way to mock just method2?
Upvotes: 1
Views: 136
Reputation: 39400
You can use the Partial Mock functionality of the testing framework that permit you to test the same class you are marked as mocked. As example, suppose the your modified class:
<?php
namespace Acme\DemoBundle\Model;
class MyClass {
public function method1()
{
$var = $this->method2();
$answer = in_array(3, $var);
// Do stuff with var to get $answer
return $answer;
}
public function method2()
{
// Do complex workings out to get $var
return array();
}
}
And tested as follow:
<?php
namespace Acme\DemoBundle\Tests;
class MyClassTest extends \PHPUnit_Framework_TestCase {
function test_method1()
{
$mockedMyClass = \Mockery::mock('Acme\DemoBundle\Model\MyClass[method2]');
$mockedMyClass->shouldReceive('method2')->once()->andReturn([1,2,3,4]); // mocked $var returned to be used in the rest of method1
$answer = $mockedMyClass->method1();
$this->assertTrue($answer); // Assertions
}
}
Hope this help
Upvotes: 2