Php setupBeforeClass之后是否有任何方法执行数据提供程序功能?

Php setupBeforeClass之后是否有任何方法执行数据提供程序功能?,php,phpunit,Php,Phpunit,我有一个单元测试类,我想在其中实例化另一个类中的对象,以便使用phpunit的setUpBeforeClass()fixture。所以,若我将在测试函数中直接使用最近实例化的对象,那个么它就可以正常工作了 如果我将此对象用于为数据提供程序创建的另一个函数中。因此,对象设置为null会导致提供程序始终首先执行 有没有办法在测试运行之前调用数据提供者 require_once('Dashboard.php'); Class Someclass extends PHPUnit_Framework_Te

我有一个单元测试类,我想在其中实例化另一个类中的对象,以便使用phpunit的setUpBeforeClass()fixture。所以,若我将在测试函数中直接使用最近实例化的对象,那个么它就可以正常工作了

如果我将此对象用于为数据提供程序创建的另一个函数中。因此,对象设置为null会导致提供程序始终首先执行

有没有办法在测试运行之前调用数据提供者

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()

请帮助缓解此问题

注意:由于我没有您的
仪表板
类的源代码,因此我在下面的示例中使用了一个随机数

在运行任何测试之前(以及在任何钩子(包括
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]];
}
注意:由于我没有您的
仪表板
类的源代码,因此我在下面的示例中使用了一个随机数

在运行任何测试之前(以及在任何钩子(包括
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]];
}

@德克·斯科尔滕是对的。您应该为每个测试创建一个新对象。这是一个很好的测试实践。坦率地说,它看起来更像是在测试数据,而不是测试代码,这很好,我想,这不是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的典型用法。假设您希望确保数据库中的每个用户都有一个缩略图(只是猜测),我将采用以下方法:

<?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;
    }
}

我不太清楚你在问什么,但听起来你可能想使用
设置
而不是
在上课前设置
<代码>设置
在每次测试之前运行,而不是对文件中的所有测试只运行一次。这可以防止您的第一个测试更改对象的状态,从而不会干扰其他测试。看一看(例4.2)谢谢你的评论,实际上我已经完成了安装夹具。当然它会工作,但是如果有多个测试用例,那么每个测试都会创建该类的对象。我想实例化一次,这样我就可以在同一个类中的任何地方使用它。这种“开销”不是问题。实际上,您希望每个测试都有新的实例。我不确定您的要求是什么,但听起来您可能想使用
setUp
而不是
setupforeclass
<代码>设置在每次测试之前运行,而不是对文件中的所有测试只运行一次。这可以防止您的第一个测试更改对象的状态,从而不会干扰其他测试。看一看(例4.2)谢谢你的评论,实际上我已经完成了安装夹具。当然它会工作,但是如果有多个测试用例,那么每个测试都会创建该类的对象。我想实例化一次,这样我就可以在同一个类中的任何地方使用它。这种“开销”不是问题。实际上,您希望每个测试都有新的实例。