2017-04-15 76 views
0

上下文:的instanceof擴展接口使用PHPUnit

我有這種接口,其延伸其它三個接口:

interface BasicTagsInterface extends TitleTagInterface, DescriptionTagInterface, KeywordsTagInterface {} 
  • TitleTagInterface只有一個getSeoTitle方法。
  • DescriptionTagInterface只有一個getSeoDescription方法。
  • KeywordsTagInterface只有一個getSeoKeywords方法。

這是我想在PHPUnit測試方法:

public function fromResource($resource) 
{ 
    if ($resource instanceof TitleTagInterface) { 
     $this->setTitle($resource->getSeoTitle()); 
    } 
    if ($resource instanceof DescriptionTagInterface) { 
     $this->setDescription($resource->getSeoDescription()); 
    } 
    if ($resource instanceof KeywordsTagInterface) { 
     $this->setKeywords($resource->getSeoKeywords()); 
    } 
} 

這是我怎麼想,到目前爲止測試:

$resource = $this->getMockBuilder(BasicTagsInterface::class)->setMethods([ 
    'getSeoTitle', 
    'getSeoDescription', 
    'getSeoKeywords', 
])->getMock(); 

$resource->method('getSeoTitle')->willReturn('Awesome site'); 
$resource->method('getSeoDescription')->willReturn('My awesome site is so cool!'); 
$resource->method('getSeoKeywords')->willReturn('awesome, cool'); 
// TagBuilder::fromResource() is the method above 
$this->tagBuilder->fromResource($resource); 

我也試過:

class A implements BasicTagsInterface { 
    public function getSeoDescription(){} 
    public function getSeoKeywords(){} 
    public function getSeoTitle(){} 
} 

// And in the test method: 
$resource = $this->getMockBuilder(A::class) // etc. 

問題: 使用此配置,$resource instanseof BasicTagsInterface返回true,另一個instanceof測試返回false

我的問題: 我怎麼能嘲笑它擴展其他接口,並獲得擴展接口instanceof測試的接口的測試情況外返回true,因爲他們應該?

回答

1

我無法找到在您的測試任何斷言,但對我來說,一切工作正常:

interface Title { function getTitle(); } 
interface Description { function getDescription(); } 
interface Resource extends Description, Title {} 

class MyObject { 
    public $title; 
    public $description; 

    function fromResource(Resource $resource) { 
     if ($resource instanceof Title) { 
      $this->setTitle($resource->getTitle()); 
     } 
     if ($resource instanceof Description) { 
      $this->setDescription($resource->getDescription()); 
     } 
    } 

    function setTitle($title) { $this->title = $title; } 
    function setDescription($description) { $this->description = $description; } 
} 

class Question43426479Test extends TestCase { 
    function testFromResource() { 
     $resourceMock = $this->getMockBuilder(Resource::class)->getMock(); 
     $resourceMock->method('getTitle')->willReturn('SomeTitle'); 
     $resourceMock->method('getDescription')->willReturn('SomeDescription'); 

     $object = new MyObject(); 
     $object->fromResource($resourceMock); 

     $this->assertEquals('SomeTitle', $object->title); 
     $this->assertEquals('SomeDescription', $object->description); 
    } 
} 

當我運行測試,我得到以下的輸出:

.                 1/1 (100%) 

Time: 66 ms, Memory: 8.00MB 

OK (1 test, 2 assertions) 

,你可以看我的測試有2個斷言。我不測試接口類型,因爲我傳遞了一個虛擬對象,我不關心它的接口,但是當它傳遞給我的Object-class的fromResource方法時它是否產生了正確的結果。相反,我堅持要在這個階級中取得預期的結果,即是否召集二傳手。

如果你想測試你的資源是否是特定類型的,我反而會創建一個類實現該接口:

class MyResource implements Resource 
{ 
    ... 
} 

然後寫一個單獨的測試確保當你建造一個MyResource是所需接口的實例:

function testResourceImplementsTitleAndDescription() 
{ 
    $resource = new MyResource(); 

    $this->assertInstanceOf(Title::class, $resource); 
    $this->assertInstanceOf(Description::class, $resource); 
} 

正如你可以看到我在這裏不使用模擬,因爲我想了解一下實際的對象沒有創建代替它的虛擬。

+0

嗯,對我而言,這是一個命名空間問題......抱歉,感謝您的幫助! – Leogout