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

phpunit Mock返回null,而原始方法返回string,php,unit-testing,testing,phpunit,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/bladetect.php的内容 use PHPUnit\Framework\TestCase; require_o

我有以下文件结构:

- module
-- phpunit.xml
-- blaat.php
-- tests
--- blaatTest.php
blaat.php的内容

class Blaat
{
    public function doSomething()
    {
        return 'my return value';
    }
}
tests/bladetect.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说它得到一个null值作为返回。
我在这里做错了什么?

不应该
只需要一次“/blaat.php”包含两个点。。像这样
require_once'../blaat.php'在tests/bladetect.php中

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

来自文档:

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


因此,这是默认行为,您需要自己操作。

这个问题可能很老,而且有一个答案被标记为正确,这在理论上是正确的。下面是一个测试用例的示例,它实现了@Matteo的建议

use Silex\Application;
use PHPUnit\Framework\TestCase;
use Ementor\Foundation\ApplicationFactory;
use Symfony\Component\HttpKernel\HttpKernelInterface;

class ApplicationFactoryTest extends TestCase
{
   /**
    * @test
    */
   public function it_can_return_a_silex_object()
   {
      $factory = $this->getMockBuilder(ApplicationFactory::class)
          ->setMethods(array('create'))
          ->getMock();

       $factory->expects($this->atLeastOnce())
          ->method('create')
          ->willReturnCallback(function(){
              return new Application();
          });

       $this->assertInstanceOf(HttpKernelInterface::class, $factory->create());
    }
 }

在我的例子中,我重复了可以在原始类中找到的逻辑。希望这能帮助像我刚才那样偶然发现这个问题的其他人。

看起来您正在用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"));
  }

}

不,另一个错误是:
致命错误:require_once():在/
中打开required'../blaat.php'(include_path=.:/usr/local/php5/lib/php')失败,这样做很好,所以在测试方法的响应时不需要使用模拟?这解释了很多。是的,您应该只模拟与测试中的
类交互的对象,对不起。我不明白。你到底是什么意思?对不起我的英语,我的意思是你应该使用mock object和expectation来模拟你正在测试的类的依赖关系。你能举个例子吗?我对phpunit很陌生,对它几乎一无所知。所以我不明白你想说什么,可能是因为我缺乏知识,而不是你的英语。
<?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"));
  }

}