Reputation: 6672
I'm writing some unit-tests for a typo3 v9.5 extension, and I can not figure how to properly mock objects when the under-test function is instanciating them using GeneralUtility::makeInstance(ObjectManager::class)->get(...)
If possible, I'd like to use the prophecy framework, but that's not mandatory.
For example, if the function under-test is like:
public function getRootline($pageUid) {
$pageService = GeneralUtility::makeInstance(ObjectManager::class)->get(PageService::class);
return $pageService->getRootLine($pageUid);
}
How could I test this and mock the Pageservice class?
I tried different variations of this solution:
$pageServiceProphecy = $this->prophesize(PageService::class);
$pageServiceProphecy->getRootLine($pageUid)->shouldBeCalled()->willReturn($myRootLine);
$omProphecy = $this->prophesize(ObjectManager::class);
$omProphecy->get(PageService::class)->shouldBeCalled()->willReturn($pageServiceProphecy);
GeneralUtility::setSingletonInstance(ObjectManager::class, $omProphecy->reveal());
But I get various cryptic errors every time. The given version raises the error:
TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException: A cache with identifier "cache_runtime" does not exist.
Upvotes: 0
Views: 533
Reputation: 6490
Actually you should make use of dependency injection in the class which exposes the getRootline()
API, then you can have the PageService
injected this way:
final class MyCustomClass {
private PageService $pageService;
public function __construct(PageService $pageService)
{
$this->pageService = $pageService;
}
public function getRootline(int $pageUid)
{
return $this->pageService->getRootLine($pageUid);
}
}
While testing you can inject a mock instead:
$pageService = $this->prophesize(PageService::class);
$myCustomObject = new MyCustomClass($pageService->reveal());
Upvotes: 2