У меня есть класс модульного теста, в котором я хочу создать экземпляр объекта из другого класса для того, чтобы я использовал 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
Пожалуйста, помогите смягчить эту проблему.
Заметка: так как у меня нет источника вашего
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]];
}
@ 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 обрабатывает этот фиксатор данных, когда вы используете провайдеров данных.