2016-04-10 12 views
0

私はSymfonyとphpspecにはかなり新しくなっていますので、ひどく批判してください。だから問題は私がPHPを常時取得しているということです。致命的なエラー:非オブジェクト上のメンバ関数write()を呼び出します。phpspec非オブジェクト上のメンバ関数への呼び出し

基本的にテストされるクラスは、出力をコンソールに書き込む必要があります。最初にコンストラクタでストリームを作成し、このストリームをコンソールの出力を担当する別のクラスに渡します。これがメインコードです。

クラスScreenshotTaker

<?php 

namespace Bex\Behat\ScreenshotExtension\Service; 

use Behat\Mink\Mink; 
use Behat\Testwork\Output\Printer\StreamOutputPrinter; 
use Bex\Behat\ScreenshotExtension\Driver\ImageDriverInterface; 
use Behat\Testwork\Output\Printer\Factory\ConsoleOutputFactory; 
/** 
* This class is responsible for taking screenshot by using the Mink  session 
* 
* @license http://opensource.org/licenses/MIT The MIT License 
*/ 
class ScreenshotTaker 
{ 
    /** @var Mink $mink */ 
    private $mink; 

    /** @var ConsoleOutputFactory $output */ 
    private $output; 

    /** @var ImageDriverInterface[] $imageDrivers */ 
    private $imageDrivers; 

    /** @var StreamOutputPrinter $outputStream */ 
    private $outputStream; 

    /** 
    * Constructor 
    * 
    * @param Mink $mink 
    * @param ConsoleOutputFactory $output 
    * @param ImageDriverInterface[] $imageDrivers 
    */ 
    public function __construct(Mink $mink, ConsoleOutputFactory $output, array $imageDrivers) 
    { 
     $this->mink = $mink; 
     $this->output = $output; 
     $this->imageDrivers = $imageDrivers; 
     $this->outputStream = new StreamOutputPrinter ($output); 
    } 

    /** 
    * Save the screenshot as the given filename 
    * 
    * @param string $fileName 
    */ 
    public function takeScreenshot($fileName = 'failure.png') 
    { 
     try { 
      $screenshot = $this->mink->getSession()->getScreenshot(); 

      foreach ($this->imageDrivers as $imageDriver) { 
       $imageUrl = $imageDriver->upload($screenshot, $fileName); 
       $this->outputStream->writeln('Screenshot has been taken. Open image at ' . $imageUrl); 
      } 
     } catch (\Exception $e) { 
      $this->outputStream->writeln($e->getMessage()); 
     } 
    } 
} 

は今、これはコンストラクタで使用されているConsoleOutputFactoryを渡すPHPSpecのtest.I'mですが、私は

PHP Fatal error: Call to a member function write() on a non-object in Behat/Testwork/Output/Printer/StreamOutputPrinter.php on line 125

この書き込み方法を取得していますStreamOutputPrinterの一部です。私はここで何が欠けているのか教えていただけますか?

ScreenshotTakerSpecは:

<?php 

namespace spec\Bex\Behat\ScreenshotExtension\Service; 

use PhpSpec\ObjectBehavior; 
use Prophecy\Argument; 
use Behat\Mink\Mink; 
use Behat\Mink\Session; 
use Behat\Testwork\Output\Printer\Factory\ConsoleOutputFactory; 
use Bex\Behat\ScreenshotExtension\Driver\Local; 
use Behat\Testwork\Output\Printer\StreamOutputPrinter; 

/** 
* Unit test of the class ScreenshotTaker 
* 
* @license http://opensource.org/licenses/MIT The MIT License 
*/ 
class ScreenshotTakerSpec extends ObjectBehavior 
{ 
    function let(Mink $mink, ConsoleOutputFactory $output, Local $localImageDriver) 
    { 
     $this->beConstructedWith($mink, $output, [$localImageDriver]); 
    } 

    function it_is_initializable() 
    { 
     $this->shouldHaveType('Bex\Behat\ScreenshotExtension\Service\ScreenshotTaker'); 
    } 

    function it_should_call_the_image_upload_with_correct_params(Mink $mink, Session $session, Local $localImageDriver) 
    { 
     $mink->getSession()->willReturn($session); 
     $session->getScreenshot()->willReturn('binary-image'); 
     $localImageDriver->upload('binary-image', 'test.png')->shouldBeCalled(); 

     $this->takeScreenshot('test.png'); 
    } 
} 

答えて

1

あなたはStreamOutputPrinterライン144であるが、別のクラスにある何かをからかっする香りですoutputFactory->createOutput()への呼び出しを模擬する必要があります。だから私は、新しいクラスにストリーム・ロジックを移動することをお勧めします例えばStreamOutputPrinterFactory、この工場を注入したい:

public function __construct(Mink $mink, StreamOutputPrinterFactory $factory, array $imageDrivers) 
{ 
    $this->mink = $mink; 
    $this->imageDrivers = $imageDrivers; 
    $this->outputStream = $factory->createNew(); 
} 

今、あなたは$this->outputStreamへの呼び出しを模擬することができます。

コンストラクタではなく、必要なときはcreateNew()も呼び出す必要があります。さらなる助けが必要な場合はお知らせください。

関連する問題