Laravel依赖注入在模拟

时间:2019-12-29 13:20:53

标签: laravel mockery

我正在尝试为此仓库编写测试:laravel.com。下面是应用程序的结构。

App \ Documentation.php

public function __construct(Filesystem $files, Cache $cache)
{
   $this->files = $files;
   $this->cache = $cache;
}

public function get($version, $page)
{
    return $this->cache->remember('docs.'.$version.'.'.$page, 5, function () use ($version, $page) {

            if ($this->files->exists($path = $this->markdownPath($version, $page))) {
                return $this->replaceLinks($version, markdown($this->files->get($path)));
            }

            return null;
    });
}

public function markdownPath($version, $page)
{
    return base_path('resources/docs/'.$version.'/'.$page.'.md');
}

DocsController.php

public function __construct(Documentation $docs)
{
     $this->docs = $docs;
}

public function show($version, $page = null)
{
    $content = $this->docs->get($version, $sectionPage);
}

这是我的测试逻辑

$mock = Mockery::mock('App\Documentation')->makePartial();

$mock->shouldReceive('markdownPath')->once()->andReturn(base_path('test/stubs/stub.md'));

$this->app->instance('App\Documentation', $mock);

$this->get('docs/'.DEFAULT_VERSION.'/stub') //It hits DocsController@show
//...

这是错误

  

调用成员函数Remember()为空

到目前为止,我尝试过的其他方式和不同的错误

1)

$mock = \Mockery::mock('App\Documentation');

$mock->shouldReceive('markdownPath')->once()->andReturn(base_path('test/stubs/stub.md'));

app()->instance('App\Documentation', $mock);
  

Mockery \ Exception \ BadMethodCallException:收到Mockery_0_App_Documentation :: get(),但未指定期望

在这里,我不想为每种方法定义期望。

2)

app()->instance('App\Documentation', \Mockery::mock('App\Documentation[markdownPath]', function ($mock) {
    $mock->shouldReceive('markdownPath')->once()->andReturn(base_path('test/stubs/stub.md'));
}));
  

ArgumentCountError:函数App \ Documentation :: __ construct()的参数太少,传递了0个且恰好期望2个

如果我们在模拟中指定方法名称(App \ Documentation [markdownPath]);构造函数不是在嘲笑,所以我们会出错。

1 个答案:

答案 0 :(得分:0)

您可以使用容器来解析真实实例(以便解析文件系统和缓存依赖项),然后根据真实实例创建部分模拟,以定义对markdownPath方法的期望。设置好模拟实例后,将其放入容器中供控制器使用。

// Resolve a real instance from the container.
$instance = $this->app->make(\App\Documentation::class);

// Create a partial mock from the real instance.
$mock = \Mockery::mock($instance);

// Define your mock expectations.
$mock->shouldReceive('markdownPath')->once()->andReturn(base_path('test/stubs/stub.md'));

// Put your mock instance in the container.
$this->app->instance(\App\Documentation::class, $mock);