phpunit骚操作之静态类的部分mock

通过官方文档以及实践得知,含有静态方法的类如果需要mock,就要使用前缀 alias: ,但是随之而来有个问题是后面无法调用这个类本身的方法,所以通过阅读源码可以使用以下方法来实现(注意!!! 此方法无法生成覆盖率):

1.创建 Helpers 类进行封装

<?php

use Mockery;
use Mockery\Generator\MockConfigurationBuilder;

class Helpers
{
    /**
     * Mock static class, you can call the original method and mock the method
     * mock 静态类,既可以调用原来的方法,又可以 mock 方法
     * @param string $class
     * @param string $cloneClassNameSuffix
     * @return Mockery\Mock
     * @throws \Exception
     */
    public static function mockAliasPartial($class, $classRealPath, $cloneClassNameSuffix = 'UnitOrigin') {
        $sourceCode = file_get_contents($classRealPath);
        preg_match('/class\s+([A-Z]\w+)/', $sourceCode, $match);
        $className = $match[1] ?? '';
        if (empty($className)) {
            throw new \Exception('get class name failed!');
        }
        // update class name
        $cloneSourceCode = preg_replace('/class\s+([A-Z]\w+)/', 'class ' . $className . $cloneClassNameSuffix, $sourceCode, 1);
        // update self:: call
        $cloneSourceCode = str_replace('self::', 'static::', $cloneSourceCode);
        eval("?>" . $cloneSourceCode);
        
        $builder = new MockConfigurationBuilder();
        $builder->setInstanceMock(true);
        $builder->setName($class);
        $target = '\\' . $class . $cloneClassNameSuffix;
        return Mockery::mock($target, $builder)->makePartial();
    }
}

2.创建静态类

class Test
{
    public static function getName($name) {
        if (empty($name)) {
            return 'default_name';
        }
        return $name;
    }
}

3.测试运行

<?php

use PHPUnit\Framework\TestCase;


class UniTest extends TestCase
{
    public function testAliasPartial() {
        $mock = Helpers::mockAliasPartial(Test::class, './Test.php');
        $actual1 =  Test::getName('');
        echo PHP_EOL;
        $mock->shouldReceive('avatar_small')->andReturn('fake name');
        $actual2 = Service::getName('');
        
        $this->assertEquals('default_name', $actual1);
        $this->assertEquals('fake name', $actual2);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值