2017-07-09 25 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