在主干之外使用factory.php进行单元测试

时间:2016-03-22 作者:EHerman

我已经编写了一个插件,正在为它设置一些单元测试。

在单元测试中,我使用WP_UnitTest_Factory 类来帮助创建帖子、用户等。

$this->factory->post->create( array( \'post_type\' => \'announcement\' ) );
我发现,当我在Travis CI上运行单元测试时WP_UnitTest_Factory 在最新版本之外的版本上失败。

Travis CI上引发的错误为:

Notice: Trying to get property of non-object in /home/travis/build/build_name/project/tests/test-helper-functions.php on line 12
这发生在4.1、4.0、3.9.2上,但不是在WP_Version=latest.

正在引用WP_UnitTest_Factory 代码(如上)创建帖子。

我的想法是WP_UnitTest_Factory 包含在trunk中,因此在最新版本上运行时,该类可用。

在旧版本上运行时,工厂类不存在,因此会引发错误。

我做了一些研究并检查了其他插件的单元测试,它们似乎完全避免使用factory类,并使用内置的wp函数(wp_insert_post()).

有没有办法解决这个问题,或者我应该重新编写测试以使用内置的WP函数,而不是WP_UnitTest_Factory 类,以便我的测试将通过旧版本的WordPress?

1 个回复
最合适的回答,由SO网友:J.D. 整理而成

问题并不是工厂类不可用,因为如果是这样,您将得到一个致命的“找不到类”错误。问题是您没有正确使用测试用例。This code (和类似)是导致问题的原因:

/**
 * Testing that timeline_express_get_announcement_date() returns what we expect
 */
public function test_timeline_express_get_announcement_date() {
    // Re-instantiate this class
    $helper_functions_test_class = new TE_Helper_Tests;
    // Create some test announcements, passing in some defaults.
    $announcement_id = $helper_functions_test_class->test_create_announcement( \'#FF6347\', \'fa-plus\', \'04/04/1989\' );
    // Grab the announcement date
    $announcement_date = timeline_express_get_announcement_date( $announcement_id );
    $comparison_date = date_i18n( get_option( \'date_format\' ), strtotime( \'04/04/1989\' ) );
    // $announcement_date = get_post_meta( $announcement_id, \'announcement_date\', true );
    $this->assertEquals( $announcement_date, $comparison_date );
}
这里您自己正在构建一个测试用例,这意味着您将跳过PHPUnit通常执行的所有设置,例如调用测试用例的setUp() 方法(其中factory 属性已设置。

所以当你打电话的时候test_create_acnnouncement() 在您刚刚构建的类上factory 属性尚未设置,这就是为什么会出现这些错误。

相反,您应该将该测试(以及其他类似测试)重构为如下内容:

/**
 * Testing that timeline_express_get_announcement_date() returns what we expect
 */
public function test_timeline_express_get_announcement_date() {
    // Create some test announcements, passing in some defaults.
    $announcement_id = $this->test_create_announcement( \'#FF6347\', \'fa-plus\', \'04/04/1989\' );
    // Grab the announcement date
    $announcement_date = timeline_express_get_announcement_date( $announcement_id );
    $comparison_date = date_i18n( get_option( \'date_format\' ), strtotime( \'04/04/1989\' ) );
    // $announcement_date = get_post_meta( $announcement_id, \'announcement_date\', true );
    $this->assertEquals( $announcement_date, $comparison_date );
}
换句话说,只需跳过创建类的新实例的部分,只需使用已有的实例即可:$this.

那么,为什么在运行最新版本的测试套件时不显示此错误?因为最新版本包括__get() 方法提供给工厂。因此,不必在最新版本的测试中设置该属性。但不要认为这是一个指示,表明您应该像之前那样手动构建测试用例,这不是一件正常的事情。

因此,为了回答您的最后一个问题,即您是否应该使用工厂,您所看到的大多数插件使用内置WordPress功能的原因可能只是因为它们不了解工厂。虽然你不必使用这些工厂,但它们的好处是你不必编造虚假的帖子内容等,工厂只会自动为你生成这些内容。

相关推荐