【问题标题】:How to test the class method which use construct variable如何测试使用构造变量的类方法
【发布时间】:2015-12-21 05:40:54
【问题描述】:

游戏.php

<?php

class Game
{
    public $db;

    public function __construct()
    {
        $this->db = new DB;
    }

    public function result()
    {
        return $this->db->data();
    }
}

DB.php

<?php

class DB
{
    public function data()
    {
        return false;
    }
}

GameTest.php

<?php

use Mockery as m;

class GameTest extends PHPUnit_Framework_TestCase
{
    public function testResult()
    {
        $game = m::mock(new Game);
        $game->shouldReceive('data')
            ->once()
            ->andReturn(true);
        $expected = $game->result();

        $this->assertTrue($expected);
    }

    public function tearDown()
    {
        m::close();
    }
}

这是我的解决方案但完全不起作用,我想如果我想从__construct 获取设置我需要模拟一个新类,我收到消息Failed asserting that false is true. 这意味着模拟的东西不起作用,如何处理用它?

【问题讨论】:

  • 以前从未使用过 Mockery,但看起来您在这里有一个 Game 对象模拟,并且正在模拟其中 Db 对象的方法?
  • 是的,通常我们会使用依赖注入,但我正在尝试使用 Mockery 的所有可能性
  • data() 不是 Game 对象的方法。据我了解, shouldReceive() 接受存在于您的模拟对象中的方法名称
  • true,hackmd.io/s/4yq_hHhA,这就是我模拟内部方法的方式,我只是尝试做同样的事情

标签: php phpunit mockery


【解决方案1】:

你不能那样做,最好的解决方案是对 $db 使用依赖注入。 这样你就可以像这样只模拟 DB...

$dbMock = m::mock('DB');
$dbMock->shouldReceive('data')
      ->once()
      ->andReturn(true);

或者你可以让你的构造函数像这样(没有 DI),但你也必须模拟那个构造函数。

【讨论】:

    【解决方案2】:

    您可以通过为 DB 类创建“实例模拟”来使用 Mockery,如下所示:

    $dbMock = Mockery::mock('overload:MyNamespace\DB');
    

    这将在创建 DB 类的新实例时“拦截”并改用 $dbMock。创建$dbMock 后,您只需为给定方法添加期望声明:

    $dbMock->shouldReceive('data')
      ->once()
      ->andReturn(true);
    

    【讨论】:

      猜你喜欢
      • 2012-05-17
      • 2017-12-04
      • 1970-01-01
      • 2016-04-08
      • 1970-01-01
      • 1970-01-01
      • 2019-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多