phpunit中的模拟类

时间:2015-07-03 19:19:57

标签: php unit-testing phpunit

我终于进入了PHP单元测试(是的,迟到总比没有好!)

我有一个Utility类,可以执行一些操作,包括验证用户对Web服务的访问权限。 Utility::authenticate方法采用Settings对象,其中包含authenticate检查的用户名等。

所以在我的测试中,我像这样嘲笑一个Settings对象:

$settings = $this->getMock('Settings', array('getSettings'));

$settings->method('getSettings')
    ->willReturn([
        'USERNAME' => 'testuser',
        'SERVER' => 'testserver'
    ]);

$mock = $settings->getSettings();

到目前为止一切顺利,但是当我尝试将该模拟对象传递给authenticate时,它会抛出一个错误:

$this->assertEquals($testvalue, Utilities::authenticate($settings));
Argument 1 passed to Utilities::authenticate() must be an instance of Settings, instance of Mock_Settings_d0361624 given

如何模拟Settings对象,使其看起来像是真实的"对象Utilities类?

编辑以添加getSettings函数:

class Settings {

private $settings;
private static $instance;

public function __construct(){
    $configfile = "config/config.ini";
    //if( !$this->settings = parse_ini_file( $configfile, true ) ){
        //die('SETTINGS OBJECT NOT FOUND OR COULD NOT BE PARSEd');
    //}
}
/**
 * @return Settings
 */
public static function getSettings(){
    if ( !self::$instance ){
        self::$instance = new Settings();
    }
    if(!utilities::authenticate(self::$instance)) die('AUTHENTICATION FAILED-- CHECK API KEY');
    return self::$instance;
}

1 个答案:

答案 0 :(得分:2)

使用错误的类名创建对象时会出现此错误消息。检查getMock方法是否使用命名空间传递完整的类名,如:

$settings = $this->getMock('Acme\DemoBundle\Model\Settings', array('getSettings'));

希望这个帮助

修改

该方法是静态的,phpunit库不支持模拟静态方法,如herehere所述。

因此,您可以使用一些支持模拟静态方法的Phake等模板框架,如here所述。作为工作示例:

public function test_authenticate()
{
    $settings = \Phake::mock('Acme\DemoBundle\Model\Settings');

    \Phake::whenStatic($settings)
        ->getSettings()
        ->thenReturn([
            'USERNAME' => 'testuser',
            'SERVER' => 'testserver'
        ]);

    $mock = $settings->getSettings();

    $testvalue = true;
    $this->assertEquals($testvalue, Utilities::authenticate($settings));
}