Mocking A Laravel Command Dependency
As the official Laravel's documentation says so I made the following command:
namespace App\Console\Commands;
use App\Model\Report;
use Illuminate\Console\Command;
use Exception;
class ExportAnualReport extends Command
{
/**
* @var string
*/
protected $description = "Print Anual Report";
/**
* @var string
*/
protected $signature = "report:anual";
public function __construct()
{
parent::__construct();
}
public function handle(Report $report): int
{
//@todo Implement Upload
try {
$reportData = $report->getAnualReport();
$this->table($reportData['headers'], $reportData['data']);
return 0;
} catch (Exception $e) {
$this->error($e->getMessage());
return 1;
}
}
}
But instead of the approach used in this question I already follow laravel's approach and recommendation and I utilize Dependency Injection in order to insert my model as a Service.
So I the meantime I thought it would be a good Idea to Unit test it:
namespace Tests\Command;
use App\Model\Report;
use Tests\TestCase;
class TripAdvisorUploadFeedCommandTest extends TestCase
{
public function setUp()
{
parent::setUp();
}
public function testFailAnualReport()
{
$this->artisan('report:anual')->assertExitCode(1);
}
public function testSucessAnualReport()
{
$this->artisan('report:anual')->assertExitCode(0);
}
}
But In my case I already have inject the Eloquent Model Report
into my command via the handle
function, so I want to mock the Report
object instance Instead of hitting the actual database.
For the record the Report
Object is the following:
namespace App\Model
use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon
use Illuminate\Database\Eloquent\ModelNotFoundException;
class Report extends Model
{
/**
* @var string
*/
protected $table = 'myapp_report_records';
/**
* @var string
*/
protected $primaryKey = 'report_id';
public function getAnualReport()
{
$now=Carbon::now();
$oneYearBefore=new Carbon($now);
$oneYearBefore->modify('-1 year');
$results=$this->where('date','>',$oneYearBefore)->where('date','<',$now)->all();
if(empty($results)){
throw new ModelNotFoundException();
}
return $results;
}
}
So how I can mock the provided Report
model?
Answer
First of all you need to create a mock of your model report class then you need to bind it to the container. this way whenever you call the report model class in your command class you'll have a mocked model class with the specific response that you are expecting.
$this->app->instance(Report::class, \Mockery::mock(Report::class, function($mock){
$mock->shouldReceive('getAnualReport')->andReturn(['headers'=>'any values', 'data'=>'any values']);
}));
Related Questions
- → "failed to open stream" error when executing "migrate:make"
- → October CMS Plugin Routes.php not registering
- → OctoberCMS Migrate Table
- → OctoberCMS Rain User plugin not working or redirecting
- → October CMS Custom Mail Layout
- → October CMS - How to correctly route
- → October CMS create a multi select Form field
- → October CMS - Conditionally Load a Different Page
- → How to disable assets combining on development in OctoberCMS
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → OctoberCms component: How to display all ID(items) instead of sorting only one ID?
- → In OctoberCMS how do you find the hint path?
- → How to register middlewares in OctoberCMS plugin?