【问题标题】:makePartial() returns Mockery\Exception\BadMethodCallException : Method does not exist on this mock objectmakePartial() 返回 Mockery\Exception\BadMethodCallException :此模拟对象上不存在方法
【发布时间】:2019-08-13 12:57:43
【问题描述】:

我正在尝试测试我的 Category 类。我正在使用 Mockery::mock() 方法,带有 'overload:' 前缀和 makePartial() 方法。

运行测试时出现此错误:

Mockery\Exception\BadMethodCallException : Method App\Models\Category::getDynamicFieldsForDocument() does not exist on this mock object

这是我的代码:

namespace App\Models;
class Category extends DictionaryBase{
    //some methods
    public function getDynamicFieldsForDocument()
    {
        $data = [];
        $parents = [];
        $allParents = $this->getParents($this->id, $parents);
        foreach ($allParents as $parentId) {

            $parent = Category::find($parentId);
            $fields = $parent->dynamicFields();
            foreach ($fields as $field) {
                $data[$field['name']] = $field;
            }
        }

        return $data;
    }
}

测试用例:

namespace Tests\Unit;

use App\Models\Category;
use Tests\TestCase;
class CategoryModelTest extends TestCase{
    //some methods
    /**
     * @runInSeparateProcess
     * @preserveGlobalState disabled
     */
    public function testGetDynamicFieldsForDocument()
    {
        $mockCategory = \Mockery::mock('overload:'.Category::class)->makePartial();
        $preparedDynamicFields = $this->prepareDynamicFields();
        $preparedCategories = $this->prepareCategories();
        $mockCategory->shouldReceive('find')->andReturn($preparedCategories[0], $preparedCategories[1], $preparedCategories[2]);
        $mockCategory->shouldReceive('getParents')->andReturn(['1a2b', '3c4d', '5e6f']);
        $mockCategory->shouldReceive('dynamicFields')->andReturn(null, $preparedDynamicFields[0], $preparedDynamicFields[1]);

        $response = $mockCategory->getDynamicFieldsForDocument();
        dd($response);
    }
}

我不知道为什么我仍然有错误。我认为当调用 ->makePartial() 方法时,它应该只模拟由 ->shouldReceive() 调用的方法


编辑:

现在我正在制作没有 :overload 的模拟实例,并以这种方式模拟 'find' 方法:

    `$mockCategory->shouldReceive('find')->andReturn($preparedCategories[0], $preparedCategories[1], $preparedCategories[2]);`

我的 find 方法如下所示:

public static function find($id) {
        return $id ? self::list(config(static::IDENT.'.fields'), (new Filter('and'))->add('id', $id, '')->toArray(),[],1,1)[0] ?? null : null;
    }

这是我的错误:

错误:App\Exceptions\ApiException([string $message [, long $code [, Throwable $previous = NULL]]])

这是因为 list 方法调用 API,所以看起来这个方法是在没有 mock 的情况下调用的。 我知道我不能模拟静态方法,但是在我之前使用 :overload 时它是可能的。现在做什么?

【问题讨论】:

  • 你能发布你的 Category 模型和 CategoryModelTest 类的命名空间吗?还要检查测试文件中的 use 声明。
  • 我更新了我的帖子,你现在可以看到它了

标签: php laravel unit-testing phpunit mockery


【解决方案1】:

删除 :overload 并将您的模拟定义为:

$mockCategory = \Mockery::mock(Category::class)->makePartial()

示例

型号:

namespace App\Models;

class Foobar extends BaseModel
{
  public function foonction()
  {   
      Foobar::find();                                                                                                                                                                                          
      return '1';
  }   
}

测试:

命名空间测试;

use Evalua\Heva\Models\Foobar;

class FoobarTest extends TestCase 
{
  public function testFoobar()
  {   
    $fooMock = \Mockery::mock('overload:'.Foobar::class)->makePartial();
    $fooMock->shouldReceive('find')->once();
    $fooMock->foonction();
  }   
}

失败:

Mockery\Exception\BadMethodCallException: Method Evalua\Heva\Models\Foobar::foonction() does not exist on this mock object

没有:overload 测试通过。

解释应该是based on what's written in the documentation about overload:

使用“overload:”为类的有效名称(当前未加载)添加前缀将生成一个别名模拟(与“alias:”一样),但创建的该类的新实例将导入在原始模拟 ($mock)。原始模拟永远不会被验证,因为它使用了新实例的期望存储。为此,我们使用术语“实例模拟”

【讨论】:

  • 非常感谢!这很有帮助,但我仍然有问题。我编辑了我的帖子。
  • 这不起作用。我还是get方法不存在。
猜你喜欢
  • 1970-01-01
  • 2015-11-13
  • 2015-03-01
  • 2016-09-17
  • 2020-01-16
  • 2013-11-04
  • 1970-01-01
  • 2019-07-23
  • 2011-12-17
相关资源
最近更新 更多