PHP и ссылки несколько неинтуитивны. Если использовать соответствующие ссылки в правильных местах, это может обеспечить большие улучшения производительности или избежать очень уродливых обходных решений и необычного кода.
Следующее приведет к ошибке:
function f(&$v){$v = true;}
f(&$v);
function f($v){$v = true;}
f(&$v);
Ни у кого из них нет чтобы они могли следовать приведенным ниже правилам, но, без сомнения, были удалены или отключены, чтобы предотвратить много путаницы.
Если они действительно работали, оба включают избыточное преобразование в ссылку, а второе также включает в себя избыточное преобразование обратно в облачную содержащуюся переменную.
Второй вариант был возможен, позволяя передавать ссылку на код, который не предназначен для работы со ссылками. Это крайне уродливо для ремонтопригодности.
Это ничего не сделает:
function f($v){$v = true;}
$r = &$v;
f($r);
В частности, он возвращает ссылку обратно в обычную переменную, поскольку вы не запрашивали ссылку.
Это будет работать:
function f(&$v){$v = true;}
f($v);
Это означает, что вы передаете ссылку без ссылки, но хотите получить ссылку, поэтому она превращается в ссылку.
Что это означает, что вы не можете передать ссылку на функцию, в которой ссылка явно не указана для того, чтобы сделать ее одной из немногих областей, где PHP является строгим при передаче типов или в этом случае больше мета-типа.
Если вам нужно больше динамического поведения, это будет работать:
function f(&$v){$v = true;}
$v = array(false,false,false);
$r = &$v[1];
f($r);
Здесь он видит, что вы хотите ссылку и уже имеете ссылку, поэтому оставите ее в покое. Он может также связывать ссылку, но я в этом сомневаюсь.
Я просто скопировал ваш MyExtension
дословно (т. е. с нулевыми изменениями) и запустил оба FooTest
и BarTest
.
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(MyExtension.class)
class FooTest {
@Test
void test() {
}
}
и
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(MyExtension.class)
class BarTest {
@Test
void test() {
}
}
И результат:
org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext@2280cdac
org.junit.jupiter.engine.descriptor.JupiterEngineExtensionContext@2280cdac
Found it, no need to store anything again!
Таким образом, getRoot()
работает как задокументировано.
Единственное объяснение того, почему вы видите два разных корня, заключается в том, что вы должны выполнять тесты в различные процессы.
Пожалуйста, имейте в виду, что экземпляр root ExtensionContext
привязан к текущему исполнению вашего тестового набора.
Итак, если вы запустите FooTest
и BarTest
один за другим в среде IDE, что фактически приведет к двум «тестовым наборам» с разными корнями. То же самое верно, если вы настроите свой инструмент построения на fork между тестовыми классами.
Принимая во внимание, что если вы выполняете оба тестовых класса вместе в одном «наборе тестов» (например, сообщая вашей среде IDE, чтобы запускать все тесты в одном и том же пакете или в одном исходном дереве), вы увидите, что есть один корень, как в вышеприведенном выше выпуске.
Обратите внимание, однако, что возникла проблема с junit-platform-surefire-provider
до версии 1.0.3, посредством чего провайдер запустил платформу JUnit для каждого тестового класса. Это дало бы появление forking , хотя Surefire фактически не запускал новый процесс JVM. Подробнее см. В https://github.com/junit-team/junit5/pull/1137 .
mvn clean install
) отображает проблему. Есть ли какая-то закулисная магия, выполняемаяjunit-platform-surefire-provider
? – Siliarus 3 April 2018 в 14:501.1.0
решает проблему! – Sam Brannen 3 April 2018 в 16:16