【问题标题】:How to mock the object manager in Typo3 unit-tests如何在 Typo3 单元测试中模拟对象管理器
【发布时间】:2021-02-01 14:26:10
【问题描述】:

我正在为typo3 v9.5 扩展编写一些单元测试,当被测函数使用GeneralUtility::makeInstance(ObjectManager::class)->get(...) 实例化对象时,我不知道如何正确模拟对象

如果可能,我想使用the prophecy framework,但这不是强制性的。

例如,如果被测函数是这样的:

public function getRootline($pageUid) {
    $pageService = GeneralUtility::makeInstance(ObjectManager::class)->get(PageService::class);
    return $pageService->getRootLine($pageUid);
}

如何测试并模拟 Pageservice 类?

我尝试了这个解决方案的不同变体:

$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());

但我每次都会遇到各种神秘的错误。 给定版本引发错误:

TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException: A cache with identifier "cache_runtime" does not exist.

【问题讨论】:

    标签: php unit-testing typo3 typo3-9.x


    【解决方案1】:

    其实你应该在暴露getRootline() API的类中使用dependency injection,然后你可以这样注入PageService

    final class MyCustomClass {
        private PageService $pageService;
    
        public function __construct(PageService $pageService)
        {
            $this->pageService = $pageService;
        }
    
        public function getRootline(int $pageUid)
        {
            return $this->pageService->getRootLine($pageUid);
        }
    }
    

    在测试时,您可以改为注入模拟:

    $pageService = $this->prophesize(PageService::class);
    $myCustomObject = new MyCustomClass($pageService->reveal());
    

    【讨论】:

    • 对不起,我应该准确地说我使用的是 Typo3 9.5,而且依赖注入似乎需要 10+...(我将编辑我的问题以完成它)跨度>
    • 视情况而定。如果您使用 Extbase,那么您可以使用相同的设置进行依赖注入。
    • 我试过了,但依赖注入似乎对我不起作用......我添加了Configuration/Services.yaml 文件,并尝试通过构造函数和injectDependency(...) 方法注入,但是typo3似乎没有注入...(尽管单元测试运行良好,因为我手动进行注入)
    • 上:感谢这个博客:daniel-siepmann.de/posts/2017/typo3-extbase-injection.html,我设法使依赖注入工作。它指定你应该用$objectManager->get(...) 来实例化你的类,而不是makeInstancenew
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2019-01-22
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    相关资源
    最近更新 更多