php - PHPUnit - 调用断言特征方法
问题描述
假设我有一个当前有方法的特征:
trait MyTrait
{
public function traitMethod()
{
return true;
}
}
现在假设这个特性被几个类使用,但我不想为每个类编写一个单元测试。相反,我只想为 trait 编写一个单元测试:
public function testTraitMethod()
{
$trait = $this->getMockForTrait(MyTrait::class);
$this->assertTrue($trait->traitMethod());
}
但问题是一个类实际上可能会覆盖 trait 的方法:
class MyClass
{
use MyTrait;
public function traitMethod()
{
return false;
}
}
在这种情况下MyClass
是做错了什么,但我不知道,因为我只测试这个特征。
我的想法是为每个类编写一个单元测试,以检查它是否正在使用该特征并且它没有覆盖该方法。如果一个类需要覆盖 trait 的方法,那么它也需要一个特定的单元测试。
目前我正在为每个实现我的特征的类编写单元测试,但它当然是到处都是复制粘贴测试。
那么有没有办法测试一个类是否调用它的底层特征方法?
解决方案
我找到了一个解决方案Reflection
,我会发布它以防有人需要它,因为我找不到与我的问题相关的任何内容。如果需要,请随意评论或添加不同的解决方案。
因此,以下测试断言$serviceClass
使用$traitClass
并且不覆盖$traitClass
除抽象方法和手动添加到$overriddenMethods
数组中的方法外声明的方法。
public function testServiceUsesTrait()
{
$serviceClass = MyClass::class;
$traitClass = MyTrait::class;
$this->assertContains($traitClass, (new \ReflectionClass($serviceClass))->getTraitNames());
$reflectedTrait = new \ReflectionClass($traitClass);
$reflectedTraitFile = $reflectedTrait->getFileName();
/**
* If $serviceClass overrides some trait methods they
* should be inserted into this array to avoid test failure.
* Additional unit-tests should be written for overridden methods.
*/
$overriddenMethods = [];
foreach ($reflectedTrait->getMethods() as $traitMethod) {
if ($traitMethod->isAbstract() || in_array($traitMethod->getName(), $overriddenMethods, true)) {
continue;
}
$classMethod = new \ReflectionMethod($serviceClass, $traitMethod->getName());
$this->assertSame($reflectedTraitFile, $classMethod->getFileName(), sprintf(
'Trait method "%s" is overridden in class "%s" thus it must be excluded from this test.',
$traitMethod->getName(), $serviceClass
));
}
}
我还尝试使用$classMethod->getDeclaringClass()
而不是比较文件名来比较声明类,但它没有用:即使类中没有重写 trait 方法,也getDeclaringClass()
总是返回类本身。
推荐阅读
- python - 将数据框列从文本更改为熊猫数据框中的数字
- javascript - (Js) 循环中未定义的标签元素创建
- php - php表单提交并感谢您带有他们名字的消息
- flutter - 是否可以为 3 种架构构建一个 apk?
- python - Tkinter 入口小部件验证 - 让我的代码更性感
- sql-server - 如何在 mulesoft 应用程序中启用 SQL Server 数据库的身份插入?
- python - 使用 pandas 将三个单独的 CSV 文件中的特定元素连接到一个 CSV 文件中
- c# - 如何使用实例化在玩家位置旁边生成对象
- amazon-web-services - 我是否总是必须明确承担角色才能访问 S3?
- ansible - 状态时的Ansible多个正则表达式