2016-04-07 15 views
0

名前付きコンストラクタを使用してファイルを作成するクラスがありますが、phpspecを使用してテストするときにファイルを作成しません。名前付きコンストラクタでのファイルの作成

私はその理由を見つけることができませんので、私のコードを見てみると、新鮮な表情になるはずです。

ここに私のFileクラスです:ここでは

<?php 

namespace Acme; 

class File 
{ 
    /** 
    * @var Path 
    */ 
    private $path; 

    /** 
    * @var FileName 
    */ 
    private $fileName; 

    private function __construct(Path $path, FileName $fileName) 
    { 
     $this->path = $path; 
     $this->fileName = $fileName; 
    } 

    public static function create(Path $path, FileName $fileName) 
    { 
     if (file_exists((string) $path . (string) $fileName)) { 
      throw new \DomainException('File already exists'); 
     } 

     if (!touch((string) $path . (string) $fileName)) { 
      throw new \DomainException('Cannot create file'); 
     } 

     return new self($path, $fileName); 
    } 
} 

私のスペック:

<?php 

namespace spec\Acme; 

use PhpSpec\ObjectBehavior; 
use Prophecy\Argument; 
use Acme\Path; 
use Acme\FileName; 

class FileSpec extends ObjectBehavior 
{ 

    private $testPath; 
    private $existingFileName = 'existingFile.extension'; 
    private $nonExistingFileName = 'nonExistingFile.extension'; 
    private $existingFilePath; 
    private $nonExistingFilePath; 

    function let() 
    { 
     $this->testPath = sys_get_temp_dir() . '/'; 
     $this->existingFilePath = $this->testPath . $this->existingFileName; 
     $this->nonExistingFilePath = $this->testPath . $this->nonExistingFileName; 

     // Creating existing file 
     if (!touch($this->existingFilePath)) { 
      throw new \Exception('Cannot create existing file for testing'); 
     } 

     // Removes non existing file 
     if (file_exists($this->nonExistingFilePath)) { 
      if (!unlink($this->nonExistingFilePath)) { 
       throw new \Exception('Cannot remove non existing file for testing'); 
      } 
     } 
    } 

    function it_does_not_create_a_file_when_the_file_already_exists(Path $path, FileName $fileName) 
    { 
     $path->__toString()->willReturn($this->testPath); 
     $fileName->__toString()->willReturn($this->existingFileName); 
     $this->beConstructedThrough('create', [$path, $fileName]); 
     $this->shouldThrow(new \DomainException('File already exists'))->duringInstantiation(); 
    } 

    function it_creates_a_new_file_if_file_does_not_exist(Path $path, FileName $fileName) 
    { 
     $path->__toString()->willReturn($this->testPath); 
     $fileName->__toString()->willReturn($this->nonExistingFileName); 
     $this->beConstructedThrough('create', [$path, $fileName]); 
     assert(file_exists($this->nonExistingFilePath)); 
    } 
} 
+0

エラーメッセージはありません。ログ/例外をチェックする – JazzCat

答えて

2

必要になるまでPHPSpecのがそうするクラスのインスタンスを作成しませんので、これはです。元のクラス自体に対するメソッド呼び出しまたは期待(つまり、should*)のみがインスタンス化され、beConstructedThroughは、についてのヒントです。 phpspecはインスタンスを取得する必要があります。

これを回避するには、いくつかのメソッドを呼び出すか、おそらく$this->shouldHaveType(File::class)を呼び出しても問題はありませんが、アプローチを考え直すことをおすすめします。最終的にを外部の何か(例えばSDK、ファイルシステム、データベースなど)に統合するのであれば、のテストを作成する方がはるかに良いでしょう。とにかくこのケースでやっていることにかなり近づいています(嘲笑は本当に必要ではありません)。 phpspecは、クラスとメソッドの動作/ロジックを指定することをより目的としています。 assert()の使用法は、これもまたヒントです。これは確かにphpspecでサポートされている仕様では慣用的ではないからです。

統合テストではPHPUnitがより一般的な目的のため、より良い選択となるでしょう。必要に応じてインスタンス化してアサーションする柔軟性があります。

関連する問題