I created a wrapper function in a helper file to wrap a globally used method, like getTimestamp(). The helper file is put in the same namespace as the file I am testing ('The model file'), a namespace like 'Project\Models\TeamName'. The hypothetical model file uses getTimestamp() function and does calculations to check from birth year. I want to test edge cases in the calculations so I overrode the 'getTimestamp()' function to always return 125 in the helper file.
However, this is causing other phpunit tests to fail that use getTimpestamp(). How can I tear it down so the 'require_once' with my helper file is undone, so the rest of the phpunit tests pass? The phpunit test class and SUT are in far away namespaces.
Right now I have a PHPUnit class (located in Project\Testing\PHPUnit\Models\TeamName)
namespace Project\Testing\PHPUnit\Models\TeamName;
require_once '/testing/phpunit/models/teamname/testHelper.php';
use Project\Models\TeamName\MyModel
class MyModelTest {
const correctAge = 75;
public function testAge(){
$model = new MyModel();
$result = $model -> calculateAgeFromBirthYear(50);
assertEquals(self::correctAge, $result);
}
}
And the helper file (located in Project\Testing\PHPUnit\Models\TeamName)
namespace Project\Models\TeamName;
function getTimestamp(){
//today is year 125
return 125;
}
And the SUT/model (located Project\Models\TeamName)
namespace Project\Models\TeamName;
class MyModel {
function calculateAgeFromBirthYear($birthYear){
$date = new DateTime();
$today = $date->getTimestamp();
return $today - $birthYear;
}
}
I don't want other phpunit classes to inherit a getTimestamp() that always returns 125, I want to undo the requires_once
So this is what worked in my case, not necessarily every case.
In the MyModel class, I put a function called "getTimestampWrapper", which then called "getTimestamp" and does nothing else. I have my calculateAgeFromBirthYear function look like this now:
namespace Project\Models\TeamName;
class MyModel {
function calculateAgeFromBirthYear($birthYear){
$today = getTimestampWrapper();
return $today - $birthYear;
}
function getTimestampWrapper(){
$date = new DateTime();
$todayWrapper = $date->getTimestamp();
return $todayWrapper;
}
}
In MyModelTest, I mocked the MyModel object, then used onConsecutiveCalls with to expect the results properly.
//make sure a function called 'getTimestampWrapper' is in your model
$model = $this->getMockBuilder(MyModel::class)
->setMethods('getTimestampWrapper')
->getMock();
//my onConsecutiveCalls will get me the fake timestamps I want
$model ->method('getTimestampWrapper')
->will(
$this->onConsecutiveCalls(...[125, 125, 100])
);
//run your assertEquals now
So now when I call $model->calculateAgeFromBirthYear(50) in my unit tests, it will call use 125, 125, 100 for the timestamps