【问题标题】:Is there any way to execute data provider fuction after setupBeforeClass?在 setupBeforeClass 之后有什么方法可以执行 dataprovider 函数吗?
【发布时间】:2019-02-05 06:22:35
【问题描述】:

我有一个单元测试类,我想在其中实例化另一个类的对象,以便我使用 phpunit 的 setUpBeforeClass() 固定装置。因此,如果我将直接在测试函数中使用该最近实例化的对象,那么它的工作正常。

如果我将此对象用于为数据提供者创建的另一个函数。所以该对象设置为 null 导致提供程序总是首先执行。

有没有办法在测试运行之前调用 dataProviders?

require_once('Dashboard.php');
Class Someclass extends PHPUnit_Framework_TestCase {

    protected static $_dashboard;
    public static function setUpBeforeClass()
    {
        self::$_dashboard = new Dashboard();
        self::$_dashboard->set_class_type('Member');
    }
    /**
     * Test Org Thumb Image Existense
     * param org profile image : array
     * @dataProvider getOrgProfileImages
     */
    public function testFieldValidation($a,$b){
        //If I call that object function here it will give the result.
        //$members = self::$_dashboard->get_members();
       //var_dump($members); Printing result as expected
        $this->assertTrue(true);
    }

    public function getOrgProfileImages() : array {
        //var_dump(self::$_dashboard);
        $members = self::$_dashboard->get_members();
        $tmp_array = ['2','2'];
        return $tmp_array;

    }

    public static function tearDownAfterClass()
    {

        self::$_dashboard = null;
    }
}

错误: 为 Someclass::testFieldValidation 指定的数据提供者无效。 在 null 上调用成员函数 get_members()

请帮助缓解此问题。

【问题讨论】:

  • 我不太确定您在问什么,但听起来您可能想使用 setUp 而不是 setUpBeforeClasssetUp 在每次测试之前运行,而不是对文件中的所有测试只运行一次。这可以防止您的第一个测试改变对象的状态,因此它不会干扰您的其他测试。看看phpunit.de/manual/6.5/en/fixtures.html(例子4.2)
  • 感谢您的评论,实际上我已经完成了 setUp 夹具。当然它会起作用,但是如果有多个测试用例,那么每个测试都会创建该类的一个对象。我想实例化一次,这样我就可以在同一个类的任何地方使用它。
  • “开销”不是问题。您实际上希望每个测试都有新的实例。

标签: php phpunit


【解决方案1】:

@dirk-scholten 是对的。您应该为每个测试创建一个新对象。这是一个很好的测试实践。坦率地说,它看起来更像是在测试数据而不是测试代码,我猜这很好,这不是 PHPUnit 的典型用法。基于您要确保数据库中的每个用户都有缩略图(只是猜测)的假设,我会选择以下内容:

<?php

class DashboardDataTest extends PHPUnit\Framework\TestCase {

    private $dashboard;

    public function setUp() {
        $this->dashboard = new Dashboard();
    }

    /**
     * Test Org Thumb Image Existence
     * param org profile image : array
     *
     * @dataProvider getOrgProfileImages
     *
     * @param int $user_id
     */
    public function testThumbnailImageExists(int $user_id){

        $thumbnail = $this->dashboard->get_member_thumbnail($user_id);

        $this->assertNotNull($thumbnail);
    }

    public function geOrgUserIDs() : array {

        $dashboard            = new Dashboard();
        // Something that is slow
        $user_ids = $dashboard->get_all_the_member_user_ids();

        $data = [];

        foreach($user_ids as $user_id){
            $data[] = [$user_id];
        }

        return $data;
    }
}

每个数据提供者将在测试前被调用一次且仅调用一次。您不需要类上的静态数据夹具,因为当您使用数据提供者时,phpunit 会为您处理数据夹具。

【讨论】:

    【解决方案2】:

    注意:由于我没有您的Dashboard 课程的来源,因此我在下面的示例中使用了随机数

    在运行任何测试之前调用提供程序(以及在任何钩子,包括beforeClass 有机会运行之前)。到目前为止,实现您所追求的最简单的方法是在类加载时填充该静态属性:

    use PHPUnit\Framework\TestCase;
    
    /** @runTestsInSeparateProcesses enabled */
    class SomeTest extends TestCase
    {
        public static $_rand = null;
    
        public function provider()
        {
            $rand = self::$_rand;
            var_dump(__METHOD__, getmypid(), 'provided rand', $rand);
            return ['rand' => [$rand]];
        }
    
        /** @dataProvider provider */
        public function testSomething($rand)
        {
            $this->expectNotToPerformAssertions();
            var_dump(__METHOD__, getmypid(), 'tested with', $rand);
        }
    
        /** @dataProvider provider */
        public function testSomethingElse($rand)
        {
            $this->expectNotToPerformAssertions();
            var_dump(__METHOD__, getmypid(), 'tested with', $rand);
        }
    }
    
    // this runs before anything happens to the test case class
    // even before providers are invoked
    
    SomeTest::$_rand = rand();
    

    或者您可以在第一次调用时在提供程序本身中实例化您的仪表板:

    public function provider()
    {
        // Instantiate once
        if (null === self::$_rand) {
            self::$_rand = rand();
        }
        $rand = self::$_rand;
        var_dump(__METHOD__, getmypid(), 'provided rand', $rand);
        return ['rand' => [$rand]];
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-15
      • 2011-01-20
      • 1970-01-01
      • 2011-02-11
      • 2020-10-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多