当所有其他类都相似且没有错误时,为什么一个phpunit测试在一个类上抛出错误?

时间:2020-01-15 作者:davemackey

我正在研究Liquid Messages 插件。它有一些基本的PHPUnit测试,当我运行PHPUnit时,除了一个测试外,其他测试都通过了。It出错:

There was 1 error:
1) GCS_Async_Test::test_class_access
Exception: Invalid GC_Sermons_Plugin property: async
/long/path/wp-content/plugins/lqd-messages/gc-sermons.php:330
/long/path/wp-content/plugins/lqd-messages/tests/test-async.php:10
奇怪的是gc布道。php包含许多与此类似的属性。它们的初始化方式如下:

protected $sermons
protected $taxonomies
protected $async
类的实例附加到属性:

        public function plugin_classes()
        {
            require_once self::$path . \'functions.php\';

            // Attach other plugin classes to the base plugin class.
            $this->sermons = new GCS_Sermons($this);
            $this->taxonomies = new GCS_Taxonomies($this->sermons);
            $this->async = new GCS_Async($this);
            $this->shortcodes = new GCS_Shortcodes($this);
        }
如果我们看一下GCS\\U布道,它类似于GCS\\U Async,因为它扩展了我们看到的另一个类:

class GCS_Sermons extends GCS_Post_Types_Base {
本质上与GCS\\U Async相同:

class GCS_Async extends WP_Async_Task {
如果我们查看这些测试,就会发现针对GCS\\U布道运行的测试与GCS\\U Async相同,但只有GCS\\U Async失败:

    function test_class_access() {
        $this->assertTrue( gc_sermons()->sermons instanceof GCS_Sermons );
    }

    function test_class_access() {
        $this->assertTrue( gc_sermons()->async instanceof GCS_Async );
    }
知道为什么吗?

1 个回复
SO网友:Tim Elsass

async属性被标记为受保护,因此通常表示它与实现的详细信息有关,而不是与功能有关。理想情况下,您应该编写测试来测试您公开的公共方法。测试您在一个类的构造函数中设置的类属性是否是已初始化的实例不会提供任何建设性的反馈。例如,测试prepare_data 在该类中,实际按照您期望的方式准备数据,这将让您知道类实例已实例化。

尽管如此,看起来你有一个PHP魔术__get 在L319上引发异常:https://github.com/LiquidChurch/lqd-messages/blob/master/gc-sermons.php#L319

所以只需添加async 处理该属性,因为它不能在类之外访问。

只是另一个注意事项最好使用assertInstanceOf 而不是测试用例的instanceof。