2016-04-10 11 views
0

Ich bin ziemlich neu in Symfony und phpspec, also zögern Sie nicht, stark zu kritisieren. Das Problem ist, dass ich ständig PHP bekomme. Schwerwiegender Fehler: Aufruf einer Member-Funktion write() auf einem Nicht-Objekt.phpspec Call zu einer Member-Funktion auf einem Nicht-Objekt

Grundsätzlich sollte die getestete Klasse die Ausgabe in die Konsole schreiben. Im Konstruktor erstelle ich zuerst einen Stream und übergebe diesen Stream dann an eine andere Klasse, die für die Ausgabe in der Konsole zuständig ist. Dies ist der Hauptcode.

Klasse 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()); 
     } 
    } 
} 

Nun ist dies die phpspec test.I'm die ConsoleOutputFactory vorbei, die im Konstruktor verwendet wird, aber ich bin

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

Dieses Schreibverfahren bekommen ist Teil von StreamOutputPrinter. Kannst du mir sagen, was ich hier vermisse?

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'); 
    } 
} 

Antwort

1

Sie sollten den Aufruf outputFactory->createOutput() verspotten, die in StreamOutputPrinter Linie 144, aber etwas spöttisch, die in einer anderen Klasse ist ein Geruch. Also würde ich empfehlen, den Strom Logik zu einer neuen Klasse zu verschieben, zB StreamOutputPrinterFactory und injizieren diese Fabrik:

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

Jetzt können Sie Anrufe zu $this->outputStream verspotten.

Sie sollten auch createNew() aufrufen, wenn es benötigt wird, nicht im Konstruktor. Lassen Sie mich wissen, wenn Sie weitere Hilfe benötigen.