背景: 我建立一个PHP应用的自动测试框架,我需要一种方法来有效地"stub out"类,其封装与外部系统通信。例如,当测试使用数据库包装类Y的类X时,我希望能够在类X上运行自动化测试时“交换”类Y的“假”版本(这样我就不必这样做了作为测试的一部分,完整设置+拆除真实DB的状态)。处理包括/需要指令在PHP
问题: PHP允许“条件包括”,这意味着基本上是包括/要求指令被作为处理的文件的“主”逻辑的一部分,例如处理:
if (condition) {
require_once('path/to/file');
}
问题是我无法弄清楚当包含文件的“main”逻辑调用“return”时会发生什么。包含文件中的所有对象(定义,类,函数等)是否导入到调用include/require的文件中?还是处理停止与返回?
例子: 考虑这三个文件:
A.inc
define('MOCK_Z', true);
require_once('Z.inc');
class Z {
public function foo() {
print "This is foo() from a local version of class Z.\n";
}
}
$a = new Z();
$a->foo();
B.inc
define('MOCK_Z', true);
require_once('Z.inc');
$a = new Z();
$a->foo();
Z.inc
if (defined ('MOCK_Z')) {
return true;
}
class Z {
function foo() {
print "This is foo() from the original version of class Z.\n";
}
}
我遵守以下行为:
$ php A.inc
> This is foo() from a local version of class Z.
$ php B.inc
> This is foo() from the original version of class Z.
为什么这是奇怪的: 如果require_once()包含所有定义的代码的对象,然后选择 “PHP A.inc” 应该抱怨的消息,如
Fatal error: Cannot redeclare class Z
如果require_once()包括o NLY定义代码对象最多的“回归”,然后选择“PHP B.inc” 应该与这样的消息抱怨:
Fatal error: Class 'Z' not found
问: 任何人都可以解释究竟什么PHP做, 这里?这对我来说很重要,因为我需要一个强大的成语来处理“嘲笑”类的包含。
首先,我我不确定你想要完成什么。单元测试不应该需要任何hacky定义或条件包含。但是,除此之外,这是一个有趣的双重行为。没有回报,你会得到重复的类错误。不确定手册是否解决这个问题。 – Matthew
@Matthew - 我无法在PHP手册中找到任何解释我在OP中描述的行为(因此是问题)的内容。至于单元测试和黑客攻击包括,我发现在实践中,以某种方式注入模拟对象(又名测试双打)并不是很容易获得超过非常适中的测试覆盖范围,并且由于PHP不会使“猴子修补”非常很容易(比如说Python),那么我不得不在黑客入侵,物理替换文件和取消类层次结构之间作出选择,以实现这一点。 – Peter