【问题标题】:phpspec Call to a member function on a non-objectphpspec 调用非对象上的成员函数
【发布时间】:2016-04-10 21:08:00
【问题描述】:

我对 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 致命错误:在非对象上调用成员函数 write() Behat/Testwork/Output/Printer/StreamOutputPrinter.php 在第 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');
    }
}

【问题讨论】:

    标签: php symfony oop behat phpspec


    【解决方案1】:

    您应该模拟对StreamOutputPrinter 第 144 行中的 outputFactory-&gt;createOutput() 的调用,但模拟另一个类中的东西是一种气味。所以我建议将流逻辑移动到一个新类,例如StreamOutputPrinterFactory,并注入这个工厂:

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

    现在您可以模拟对$this-&gt;outputStream 的任何调用。

    您还应该在需要时调用createNew(),而不是在构造函数中。如果您需要进一步的帮助,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-02
      • 2010-09-26
      • 2012-04-20
      相关资源
      最近更新 更多