phpunit Mock返回null,而原始方法返回string

时间:2017-03-15 13:13:27

标签: php unit-testing testing phpunit

我有这个文件结构:

- module
-- phpunit.xml
-- blaat.php
-- tests
--- blaatTest.php

blaat.php的内容

class Blaat
{
    public function doSomething()
    {
        return 'my return value';
    }
}

tests / blaatTest.php的内容

use PHPUnit\Framework\TestCase;

require_once './blaat.php';

class blaatTest extends TestCase
{ 
    public function testCanBeCreatedFromValidEmailAddress(): void
    {
        $stub = $this->createMock(Blaat::class);

        $this->assertEquals('foo', $stub->doSomething());
    }
}

phpunit.xml的内容

<?xml version="1.0" encoding="UTF-8"?>
<phpunit
        bootstrap="./tests/bootstrap.php">
    <testsuites>
        <testsuite name="unit">
            <directory>tests</directory>
        </testsuite>
    </testsuites>
    <filter>
        <blacklist>
            <directory suffix=".php">vendor</directory>
        </blacklist>
    </filter>
</phpunit>

当我在终端中运行phpunit时(当我在modules文件夹中时)我得到了这个:

PHPUnit 6.0.8 by Sebastian Bergmann and contributors.

F                                                     1 / 1 (100%)

Time: 427 ms, Memory: 22.00MB

There was 1 failure:

1) blaatTest::testCanBeCreatedFromValidEmailAddress
Failed asserting that null matches expected 'foo'.

/path/to/module/tests/blaatTest.php:19

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

这怎么可能?我的方法将始终返回一个字符串,但phpunit说它获得一个null值作为返回。 我在这里做错了什么?

3 个答案:

答案 0 :(得分:3)

来自文档(Chapter 9. Test Doubles)

  

默认情况下,原始类的所有方法都替换为   只返回null的虚拟实现(不调用   原方法)。使用will($this->returnValue())方法,用于   例如,您可以配置这些虚拟实现以返回a   调用时的值

所以这是默认行为,你需要自己设置。

答案 1 :(得分:0)

您似乎在Drupal中进行测试。我发现需要模拟一个长的构造函数的情况,因为它包含我们不在乎的参数。尽管缺少-> setMethods(NULL)

,但您的实现是正确的

请参阅我维护的webp模块示例:

<?php
namespace Drupal\Tests\phpunit_example\Unit;
use Drupal\Core\Image\ImageFactory;
use Drupal\Tests\UnitTestCase;
use Drupal\webp;

class WebpTest extends UnitTestCase {
  protected $webp;
  /**
   * Before a test method is run, setUp() is invoked.
   * Create new unit object.
   */
  public function setUp() {
    // Mock the class to avoid the constructor.
    $this->webp = $this->getMockBuilder('\Drupal\webp\Webp')
      ->disableOriginalConstructor()
      ->setMethods(NULL)
      ->getMock();
  }

  /**
   * @covers Drupal\webp\Webp::getWebpFilename
   */
  public function testgetWebpFilename() {
    $this->assertEquals("testimage.webp", $this->webp->getWebpFilename("testimage.jpg"));
    $this->assertEquals("testimage2.webp", $this->webp->getWebpFilename("testimage2.jpg"));
  }

}

答案 2 :(得分:-1)

require_once './blaat.php';不应该包含两个点...就像test / blaatTest.php中的require_once '../blaat.php';一样?

如果我理解您的目录结构blaat.php位于另一个(上层)目录中,但您正在引用当前目录。