Я пишу свой phpunit test
, Мне нужно инициализировать dataprovider
способ сгруппировать один из моих тестов. Но я не могу получить статические переменные, объявленные в setUpBeforeClass
метод. Эти переменные возвращаются null
мне.
Когда сделал поиск в Google, в документации говорилось, что dataprovider
методы будут выполняться раньше setUpBeforeClass
,
Есть ли способ переопределить это и сделать доступ к статической переменной из dataprovider
?
Образец кода
настройка перед функцией класса
public static function setUpBeforeClass()
{
self::sampleVariable = 'Sample Data';
}
функция провайдера данных
public function sampleDataProvider()
{
echo self::sampleVariable;
}
Причина, по которой поставщики данных не связаны с процессом настройки тестового набора, заключается в том, что они могут быть определены как методы внешнего класса. Также речь идет о введении данных в тесты. Рассмотрим такой код:
class SampleTest extends PHPUnit_Framework_TestCase
{
public function __construct($name = null, array $data = array(), $dataName = '') {
parent::__construct($name, $data, $dataName);
var_dump('constructed');
}
public static function setUpBeforeClass() {
parent::setUpBeforeClass();
var_dump('beforeClass');
}
public function setUp(){
var_dump('before');
}
/**
* @dataProvider sampleDataProvider
*/
public function testMethod($expected, $actual) {
var_dump('test');
$this->assertEquals($expected, $actual);
}
public function sampleDataProvider() {
var_dump('dataProvider');
return [
[1, 1],
[2, 2],
];
}
}
при запуске вы заметите, что первым SampleTest
создается экземпляр, затем вызывается dataProvider, затем два экземпляра SampleTest
создается (один метод тестирования умножает два набора данных из провайдера данных), затем перед запуском метода Class, затем метод теста запускается дважды с введением наборов данных из провайдера.
Не совсем понятно, каков ваш конкретный вариант использования, но может быть можно было бы преобразовать вышеупомянутый случай в нечто подобное:
class AnotherSampleTest extends PHPUnit_Framework_TestCase
{
public function testMethod() {
foreach ($this->sampleDataProvider() as $dataSet) {
list($expected, $actual) = $dataSet;
$this->assertEquals($expected, $actual);
}
}
public function sampleDataProvider() {
return [
[1, 1],
[2, 2],
];
}
}
Вот sampleDataProvider
это просто обычный метод, так что вы отвечаете, как и когда вызывать его, и в любом случае он вызывается после setUpBeforeClass
а также setUp
так что у него есть доступ к любому материалу, настроенному или измененному там, так что вы можете вносить любые необходимые изменения.
Недостатком такого подхода является то, что вы фактически теряете разбиение одного метода тестирования на несколько. Таким образом, это будет один тест с несколькими утверждениями по сравнению с несколькими тестами с несколькими утверждениями на каждый. Также вам, возможно, придется позаботиться о настройке (я имею в виду, что вам может потребоваться обновить что-то перед каждой итерацией) — это можно решить, вызвав вызов setUp
вручную (на первый взгляд).
Не думайте, что можно сделать какие-либо дальнейшие предложения без каких-либо подробностей о вашем конкретном случае использования.
попробуйте объявить переменную sampleVariable как
статичен и проверен.
class MyClass
{
private static $sampleVariable;
}
PHPUnit обрабатывает методы провайдера данных странно. Они не вызываются из того же объекта, на котором выполняются тесты, поэтому в объекте, к которому выполняется вызов DP, setupBeforeClass
не был запущен. Это чертовски глупое ИМО, но я уверен, что есть причина, по которой это было сделано так, как это было (xmike объясняет это в своем ответе на самом деле. В конце концов, не так глупо ;-).
Учитывая, что ваше присваивание является просто статическим значением (в любом случае в вашем примере), вы не можете просто объявить его как свойство класса вместо того, чтобы устанавливать его через setUpBeforeClass
? Я полагаю, что ситуация может быть более сложной, чем демонстрирует ваш пример, препятствующий такому подходу: у меня есть только ваш пример, на котором основаны мои предложения.
Другая вещь, которую нужно сделать, это абстрагировать логику от setUpBeforeClass
в отдельный метод, и вызовите этот метод из обоих sampleDataProvider
, а также setUpBeforeClass
,