确保特征满足接口的 PHPUnit
PHPUnit ensuring a trait satisfies an interface
让我们看一下 psr/log
中的代码,特别是:
如你所知,trait 不能实现接口,所以这两部分需要class才能成功连接在一起。
假设我介绍了特征测试(通过 PHPUnit 的 getMockForTrait
相对容易)。接下来要测试的是我想证明特征满足接口.
从代码上看,还是比较简单的:
public function testThatTraitSatisfiesInterface()
{
$className = 'test_class_' . uniqid();
$classCode = sprintf(
'class %s implements %s { use %s; }',
$className,
LoggerAwareInterface::class,
LoggerAwareTrait::class
);
eval($classCode); // ewww :see_no_evil:
new $className(); // no errors? good, test successful
}
这里有一些问题:
- 我想尽可能避免
eval()
(即使我知道无论如何它都是驱动 PHPUnit 的原因),但是..
- 如果可能的话,我宁愿使用 PHPUnit 的功能
所以最大的问题是,还有其他选择吗?
如何将 class 创建为测试资产:
namespace Foo\Bar\Test\Asset;
use Psr\Log;
final class LoggerAware implements Log\LoggerAwareInterface
{
use Log\LoggerAwareTrait;
}
然后断言它实现了接口:
namespace Foo\Bar\Test;
use PhpUnit\Framework;
use Psr\Log;
final class LoggerAwareTest extends Framework\TestCase
{
public function testImplementsLoggerAwareInterface()
{
$loggerAware = new Asset\LoggerAware();
$this->assertInstanceOf(Log\LoggerAwareInterface::class, $loggerAware);
}
}
让我们看一下 psr/log
中的代码,特别是:
如你所知,trait 不能实现接口,所以这两部分需要class才能成功连接在一起。
假设我介绍了特征测试(通过 PHPUnit 的 getMockForTrait
相对容易)。接下来要测试的是我想证明特征满足接口.
从代码上看,还是比较简单的:
public function testThatTraitSatisfiesInterface()
{
$className = 'test_class_' . uniqid();
$classCode = sprintf(
'class %s implements %s { use %s; }',
$className,
LoggerAwareInterface::class,
LoggerAwareTrait::class
);
eval($classCode); // ewww :see_no_evil:
new $className(); // no errors? good, test successful
}
这里有一些问题:
- 我想尽可能避免
eval()
(即使我知道无论如何它都是驱动 PHPUnit 的原因),但是.. - 如果可能的话,我宁愿使用 PHPUnit 的功能
所以最大的问题是,还有其他选择吗?
如何将 class 创建为测试资产:
namespace Foo\Bar\Test\Asset;
use Psr\Log;
final class LoggerAware implements Log\LoggerAwareInterface
{
use Log\LoggerAwareTrait;
}
然后断言它实现了接口:
namespace Foo\Bar\Test;
use PhpUnit\Framework;
use Psr\Log;
final class LoggerAwareTest extends Framework\TestCase
{
public function testImplementsLoggerAwareInterface()
{
$loggerAware = new Asset\LoggerAware();
$this->assertInstanceOf(Log\LoggerAwareInterface::class, $loggerAware);
}
}