首页 > 解决方案 > 使用 PHPUnit + Mockery 的静态属性和方法测试函数

问题描述

我必须在 PHP 项目中添加单元测试。我为此使用 PHPUnit 以及 Mockery。但我有一个问题。

请参阅下面我必须测试的功能:

<?php

/**
 * Return the translation corresponding to the argument $text
 * @param string $text
 * @return string
 */
function translate(string $text) {
    // we check that all translations have been loaded in the static property $translations
    // if not it will be loaded by getTranslation
    if (empty(LanguageObject::$translations)) {
        LanguageObject::getTranslation();
    }
    // we formatte the $text argument according to the agreed format
    $key = str_replace(' ', '_', strtoupper($text));
    // we check if we need the translation's abbreviation according to the type of the client: mobile or not
    if (LanguageObject::getAbbreviation()) {
        if (!preg_match('%(_ABRV\*)$%', $key)) {
            $tmpKey = $key . '_ABRV*';
        } else {
            $tmpKey = $key;
        }
        if (!empty(LanguageObject::$translations[$tmpKey])) {
            $key = $tmpKey;
        }
    }
    
    // we get the translation
    if (!empty(LanguageObject::$translations[$key])) {
        return str_replace("'", '&#39;', LanguageObject::$translations[$key]);
    } else {
        // if it doesn't exist so we create the entry in database with $key but with empty translation
        // and we return the $key
        if (!isset(LanguageObject::$translations[$key])) {
            getObject('LanguageObject')->save(['lang_key' => $key, 'lang' => LanguageObject::$fields['lang']['default']]);
            LanguageObject::$translations[$key] = $key;
        }
        return $key;
    }
}

在这个函数中,我们使用了 LanguageOject 的 3 个静态属性和 2 个静态方法。

如果我创建这样的基本测试:

<?php

class UtilityTest extends \Mockery\Adapter\Phpunit\MockeryTestCase {
    /**
     * Test function translate with the LanguageObject::$translations property empty at the beginning of the execution
     */
    public function testFunctionVTextWithEmptyTranslationsStaticVar() {
        // We mock all the class LanguageObject
        // We have to use alias feature for mock static method
        // Here all methods used in function translate must be mock
        // So we can control the return of each them
        $langMock = Mockery::mock('alias:' . LanguageObject::class);
        $langMock->shouldReceive('getTranslation')->once()->andReturn(['CAT' => 'Chat']);
        $langMock->shouldReceive('getAbbreviation')->once()->andReturn(false);
        
        $this->assertEquals('Chat', translate('cat'));
    }
}

我收到了 PHPUnit 的错误:

Error: Access to undeclared static property: LanguageObject::$fields

他是否存在在模拟我的静态属性的类中声明的方法?

谢谢

标签: phpphpunitmockery

解决方案


推荐阅读