我对Symfony和phpspec非常陌生,所以请随意严厉批评。因此,问题是,我经常会遇到PHP致命错误:调用非对象上的成员函数write()。
基本上,被测试的类应该将输出写到控制台。在构造函数中,我首先创建流,然后将这个流传递给另一个类,它负责控制台中的输出。这是主要代码。
类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());
}
}
}这是phpspec测试,我正在传递构造函数中使用的ConsoleOutputFactory,但是我得到了
PHP致命错误:在第125行的Behat/Testwork/Output/Printer/StreamOutputPrinter.php中调用非对象的成员函数写()
这个写方法是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');
}
}发布于 2016-04-11 08:13:35
您应该模拟对outputFactory->createOutput()的调用,该调用位于StreamOutputPrinter第144行中,但嘲笑另一个类中的某些内容是一种难闻。因此,我建议将流逻辑移动到一个新的类,例如StreamOutputPrinterFactory,并注入这个工厂:
public function __construct(Mink $mink, StreamOutputPrinterFactory $factory, array $imageDrivers)
{
$this->mink = $mink;
$this->imageDrivers = $imageDrivers;
$this->outputStream = $factory->createNew();
}现在您可以模拟对$this->outputStream的任何调用。
您还应该在需要时调用createNew(),而不是在构造函数中调用。如果你需要进一步的帮助,请告诉我。
https://stackoverflow.com/questions/36535568
复制相似问题