phpunit - 如何为静态方法编写 PHP 单元测试

标签 phpunit

我是 PHP 单元测试的新手。我正在尝试为以下功能创建单元测试:

    $context = $args[0];

    if (Subscriber::instance()->isSubscriber()) {
        $context['body_class'] .= ' ' . $this->bodyClass;
    }

    return $context;

这非常简单,如果用户是订阅者,则在数组中添加类名。订阅者是一个类,它有一个返回 true 或 false 的静态实例方法。

到目前为止我已经写了这个但我认为这是不正确的:

$subscriber = $this->getMockBuilder(Subscriber::class)
    ->disableOriginalConstructor()
    ->setMethods(['isSubscriber'])
    ->getMock();

$subscriber->expects($this->once())
    ->method('isSubscriber')
    ->will($this->returnValue(true));

$this->assertInternalType('bool',$subscriber->isSubscriber());

如有任何帮助,我们将不胜感激。

最佳答案

是的,您可以使用 PhpUnit 模拟 PHP 静态方法连同 Mockery !

案例:待测类Foo(Foo.php)使用ToBeMocked类的静态方法mockMe

<?php

namespace Test;

use  Test\ToBeMocked;

class Foo {

    public static function bar(){
        return 1  + ToBeMocked::mockMe();        
    }
}

ToBeMocked 类 (ToBeMocked.php)

<?php

namespace Test;

class ToBeMocked {

    public static function mockMe(){
        return 2;                
    }
}

带有模拟静态方法(使用 Mockery)的 PhpUnit 测试文件(FooTest.php):

<?php

namespace Test;

use Mockery;
use Mockery\Adapter\Phpunit\MockeryTestCase;

// IMPORTANT: extends MockeryTestCase, NOT EXTENDS TestCase
final class FooTest extends MockeryTestCase 
{
    protected $preserveGlobalState = FALSE; // Only use local info
    protected $runTestInSeparateProcess = TRUE; // Run isolated

    /**
     * Test without mock: returns 3
     */
    public function testDefault() 
    {

        $expected = 3;
        $this->assertEquals(
            $expected,
            Foo::bar()
        );
    }

     /**
     * Test with mock: returns 6
     */
    public function testWithMock()
    {
        // Creating the mock for a static method
        Mockery::mock(
        // don't forget to prefix it with "overload:"
        'overload:Geko\MVC\Models\Test\ToBeMocked',
        // Method name and the value that it will be return
        ['mockMe' => 5]
    );
        $expected = 6;
        $this->assertEquals(
            $expected,
            Foo::bar()
        );
    }
}

运行这个测试:

$ ./vendor/phpunit/phpunit/phpunit -c testes/phpunit.xml --filter FooTest
PHPUnit 9.5.4 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.0.3
Configuration: testes/phpunit.xml

..                                                                  2 / 2 (100%)

Time: 00:00.068, Memory: 10.00 MB

OK (2 tests, 3 assertions)

关于phpunit - 如何为静态方法编写 PHP 单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54256172/

相关文章:

phpunit - ZF2单元测试专辑模块返回路由问题

php - 测试覆盖特征方法执行

php - 集成测试 PHPUnit 和 Phinx

phpUnit 与 Symfony

php - 单元测试 Symfony Messenger

PHPUnit:syntaxCheck 配置参数究竟代表什么

phpunit - Laravel 4 存储库验证和测试

phpunit 仅为特定文件夹生成 html 格式的覆盖率报告

osx-lion - Mac osx Lion phpunit 需要(/usr/lib/php/PHPUnit/Autoload.php)

mocking - 具有多个 Expects() 调用的 PHPUnit 模拟