首页 > 解决方案 > 用 Mockery 和 PHPUnit 模拟一个类的常量和方法

问题描述

Mockery 的新手......我正在测试一个调用另一个类(Foo->getData)的方法的类(在我过于简单的平淡示例中为 Buzz),并且我有一个模拟这个方法的模拟效果很好。现在我添加了对类常量(Foo::FIZZ)的检查,并且由于未定义常量而导致我的测试中断。

我试图通过映射常量来添加常量,如Mockery Docs here中所示,但它仍然说常量 FOO\Bar::FIZZ 未定义。我还没有找到任何其他方法来为我的 Mockery 模拟设置常量。任何帮助,将不胜感激!

约束:由于模拟类内部存在一些硬依赖,我必须使用重载 Mockery 。

namespace Foo; 

class Bar() {
  const FIZZ = 'hello';

  public function getData() {
    //retrieve $data from database
    return $data;
  }
}

class Buzz() {

  public function returnResult() {
    $result = Foo\Bar->getData();
    if ($result !== Foo\Bar::FIZZ) { // if result is different than my constant, return it
      return $result;
    }
    return false;
  }
}

在我的测试中:

use PHPUnit\Framework\TestCase;
use Mockery;
use Foo;

class BuzzTest extends TestCase {

   \Mockery::getConfiguration()->setConstantsMap([
    'Bar' => [
        'FIZZ' => 'hello',
    ]
  ]);

  public function testBuzzRejectsIfEqual(): void {

        $externalMock = \Mockery::mock('overload:\Foo\Bar')
            ->shouldReceive('getData')
            ->andReturn('hello');

        $obj = new \Foo\Buzz();
        $actual = $obj->returnResult();
        $this->assertEquals($actual, false);
  }
}

标签: unit-testingphpunitmockery

解决方案


感谢这篇很棒的文章https://blog.gougousis.net/mocking-static-methods-with-mockery/我终于能够使用命名模拟来完成这项工作。

use PHPUnit\Framework\TestCase;
use Mockery;
use Foo;

class BuzzTest extends TestCase {


  public function testBuzzRejectsIfEqual(): void {

        $externalMock = \Mockery::namedMock(Foo\Bar:class, BarStub::class)
            ->shouldReceive('getData')
            ->andReturn('hello');

        $obj = new \Foo\Buzz();
        $actual = $obj->returnResult();
        $this->assertEquals($actual, false);
  }
}

class BarStub {
  const FIZZ = 'hello';
}

推荐阅读