2017-07-09 26 views
1

让我们来看看在psr/log代码,具体为:的PHPUnit确保特质满足接口

如你所知,一个特质无法实现一个接口,所以这两个部分需要一个类才能成功连接在一起。

比方说,我介绍了性状的测试(通过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的功能,如果可能的话

所以最大的问题是,有没有其他的选择?

+0

为什么这么在意?一个类实现一个接口比它如何实现更重要。 – localheinz

+0

这里的重点不是课堂,而是特质。的确,我不关心课堂。 – Christian

回答

3

如何只创建一个类的测试资产:

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); 
    } 
} 
+0

这是一种可能性。 – Christian

+1

与逐字创建模拟对象的良好答案和建议。断言是不需要恕我直言。如果接口不会(完全)满足,PHP会给对象创建一个致命错误,请参阅https://3v4l.org/gAlRI - 如果PHPUnit捕获到这个错误(可捕获错误)或退出255退出代码(防止进一步测试) - 我想这取决于使用的PHP版本。这个断言在任何情况下都不会被调用。所以测试更多的是安全检查(甚至根本不需要,但这是主观的,因为我不能说OP)。 – hakre

+0

@hakre这个断言是非常有用的,因为它可以明确我们所关心的。如果我们配置严格的测试不会声明任何东西(请参阅https://phpunit.de/manual/current/en/risky-tests.html),这也很有用。 – localheinz