Есть ли способ выполнить функцию поставщика данных после setupBeforeClass? - PullRequest
0 голосов
/ 30 августа 2018

У меня есть класс модульного тестирования, в котором я хочу создать экземпляр объекта из другого класса, чтобы я использовал фиксаторы setUpBeforeClass () phpunit. Так что, если я буду использовать этот недавно созданный объект непосредственно в тестовой функции, то он работает нормально.

Если я буду использовать этот объект в другой функции, которая была создана для поставщиков данных. Таким образом, этот объект устанавливается в ноль, потому что провайдеры всегда выполняются первыми.

Есть ли способ вызвать 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, недействителен. Вызов функции-члена get_members () со значением null

Пожалуйста, помогите смягчить эту проблему.

Ответы [ 2 ]

0 голосов
/ 31 августа 2018

@ 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 обрабатывает этот фиксатор данных, когда вы используете провайдеров данных.

0 голосов
/ 31 августа 2018

Примечание : поскольку у меня нет источника вашего Dashboard класса, я использую случайное число в приведенных ниже примерах вместо

Провайдеры вызываются до запуска любых тестов (и до того, как у всех хуков, включая beforeClass есть шанс запустить). Безусловно, самый простой способ добиться того, что вам нужно, это заполнить это статическое свойство для класса load:

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]];
}
...