Reputation: 1140
I'm trying to write test for this repo: laravel.com. below is the app's structure.
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);
}
here is my test logic
$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
//...
here is the error
Call to a member function remember() on null
Different ways I've tried so far and different errors
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: Received Mockery_0_App_Documentation::get(), but no expectations were specified
Here I don't wanna define expectation for each methods.
2)
app()->instance('App\Documentation', \Mockery::mock('App\Documentation[markdownPath]', function ($mock) {
$mock->shouldReceive('markdownPath')->once()->andReturn(base_path('test/stubs/stub.md'));
}));
ArgumentCountError: Too few arguments to function App\Documentation::__construct(), 0 passed and exactly 2 expected
If we specify method name in mock (App\Documentation[markdownPath]); the constructor is not mocking, so we get error.
Upvotes: 0
Views: 1131
Reputation: 62228
You can use the container to resolve a real instance (so that the filesystem and cache dependencies are resolved), and then create a partial mock from your real instance in order to define the expectation for the markdownPath
method. Once your mock instance is setup, put it into the container for the controller to use.
// 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);
Upvotes: 0