检查类是不是具有使用 PHPUnit 定义的常量的正确方法
Posted
技术标签:
【中文标题】检查类是不是具有使用 PHPUnit 定义的常量的正确方法【英文标题】:Correct way to check if a class has a constant defined with PHPUnit检查类是否具有使用 PHPUnit 定义的常量的正确方法 【发布时间】:2017-01-10 05:08:20 【问题描述】:我试图找出最好的或正确的方法来检查一个类是否有一个用 phpUnit 定义的常量。 PHPUnit 文档似乎没有涵盖这一点,这让我想知道我是否通过测试来做正确的事情 - 但它是我的课程的一个重要特性。
我有以下课程:
PurchaseManager.php
/**
* Message sent when a course has been purchased
*/
const COURSE_PURCHASED_MESSAGE = 'coursePurchasedMessage';
...它的部分测试类有这个测试:
PurchaseManagerTest.php
public function testCoursePurchasedMessageConstant()
$pm = new PurchaseManager();
$this->assertTrue(defined(get_class($pm) . '::COURSE_PURCHASED_MESSAGE'));
这是正确的吗?它通过了,但我只是想知道这是否准确和最佳实践。
我正在使用 PHPUnit 5.0.8。
【问题讨论】:
【参考方案1】:我为此目的使用反射类。它有getConstants
方法,该方法返回一个关联数组[<constant_name> => <constant_value>, ...]
。
类似:
public function testHasSiteExportedConstant()
$mailer = new \ReflectionClass(SiteExporter::class);
$this->assertArrayHasKey('SITE_EXPORTED', $mailer->getConstants());
【讨论】:
谢谢。与我的方法相比,使用反射有什么优势? 对于简单的情况,这两种方法都很好,但对于更复杂的测试,反射方法更易于使用、阅读和维护,因为它们不需要额外的操作(如defined
、get_class
,连接,::
)。
稍微好一点,因为更直接的方式是$this->assertTrue($mailer->hasConstant('SITE_EXPORTED')
。【参考方案2】:
我永远不会测试常量、属性或方法是否存在。当然,除非您正在测试代码生成器。
【讨论】:
感谢您的评论,我内心有一些东西告诉我出于某种原因我不应该这样做,我不知道为什么。我已经使用其他工具(例如 PhpSpec)编写了测试,然后检查了类的存在。常量是我课程的重要组成部分,如果它丢失/更改了,那么我想知道它,但是你是说这不是 PHPUnit 的正确用法吗? 你能解释一下原因吗? 如果使用单元测试也与您的代码公开呈现给其他代码的内容形成伪“合同”,并且其他代码使用该常量,并且它发生变化,那么它被单元测试,让你知道你的“合同”也改变了。也许单元测试是错误的地方。¯\_(ツ)_/¯
我认为,几乎所有复杂的项目都离不开一些旨在弥补设计缺陷的偶尔(希望是暂时的)hack。而这样的 hack 需要更好的测试覆盖率,正是因为它们不同寻常且不明显。例如。依赖于一些常数的存在:-)
我同意 Sebastian 的观点,即您不应该测试事物的内部运作,而应该只测试“接口”,即在特定输入上给出的输出行为。但是,我来到这里是否要测试公共常量的存在(这很糟糕,我知道,但事实就是如此);并且由于它是公开的,因此它在某种程度上是一个相当大的接口,因此我对其进行了测试。以上是关于检查类是不是具有使用 PHPUnit 定义的常量的正确方法的主要内容,如果未能解决你的问题,请参考以下文章
如何从 phpunit.xml 而不是应用程序配置文件访问环境变量