There is a function in my codebase (legacy), which has:
function test()
{
method1("#input a")
method2("test")
method3(1,2)
}
given the fact it calls other methods
, how one will write a good unit testing for these sort of functions?
First, I do not think such a behavior as you described even need to have a unit test. BUT, If you really need to check if the methods are called with specific parameters (or even any parameters). There is a way you could do that, you could use a mocking framework like ShortifyPunit: https://github.com/danrevah/ShortifyPunit
Follow this steps:
For example if your class is using the dependency injection, which is crucial for unit testing like the following class:
class SomeClass {
private $obj;
public function __construct($obj) {
$this->obj = $obj;
}
public function test()
{
$this->obj->method1("#input a")
$this->obj->method2("test")
$this->obj->method3(1,2)
}
}
You could write a unit test as follows:
public function testMethodCalled()
{
$mockedObj = ShortifyPunit::mock('object');
$class = new SomeClass($mockedObj);
// Stub the methods so you could verify they were called
ShortifyPunit::when($mockedObj)->method1(anything())->returns(1);
ShortifyPunit::when($mockedObj)->method2(anything())->returns(2);
ShortifyPunit::when($mockedObj)->method3(anything(), anything())->returns(3);
$class->test(); // run test() method
// Verify it was called
$this->assertTrue(ShortifyPunit::verify($mockedObj)->method1(anything())->calledTimes(1));
$this->assertTrue(ShortifyPunit::verify($mockedObj)->method2(anything())->calledTimes(1));
$this->assertTrue(ShortifyPunit::verify($mockedObj)->method3(anything(), anything())->calledTimes(1));
}
given the fact it calls other
methods
(…)
It doesn't matter what it calls. From consumer (caller) point of view the end result is important. You always test the end result. The fact that some other methods are called is irrelevant implementation detail (in most cases).
I suggest simple exercise - inline method1
, method2
and method3
bodies into test
method. Would you have problems identifying what to test?
You want to test the public contract, or observable behavior - the end result of method call visible for someone calling it (many different actors might call your method - other parts of program, unit test or system user; each should experience the same observable behavior).
Now, back to the "end result"/"method's observable behavior" which was mentioned several times. It can be one of three things:
You need to identify the end result and test against it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With