I am trying to write some unit tests for my controllers.
I have implemented an interface and repository, this is passed in to the controller via Dependancy Injection
I have written a unit test that mocks the interface and New's up an instance of a controller.
My test is falling with the following error
Mockery\Exception\InvalidCountException : Method find(<Any Arguments>) from Mockery_0_App_Interfaces_VenueRepositoryInterface should be called
exactly 1 times but called 2 times.
Ultimately i want to check then when the index method is called on the controller, then it interacts correctly with the interface hence the desire to mock it. I will write further tests to actually test the interface implementation.
VenueControllerTest
<?php
namespace Tests\Unit;
use \Mockery;
use Tests\TestCase;
use App\Http\Controllers\VenueController;
class VenueControllerTest extends TestCase
{
protected $venueRepositoryInterface;
protected $mock;
public function setUp()
{
parent::setUp();
$this->mock = \Mockery::mock('App\Interfaces\VenueRepositoryInterface');
}
public function tearDown()
{
Mockery::close();
}
public function testControllerIndex()
{
$this->mock->shouldReceive('find')->once()->andReturn(2);
$venueController = new VenueController($this->mock);
$venueController->index();
$this->assertEquals($this->mock->find(1),2);
}
}
VenueController.php
<?php
namespace App\Http\Controllers;
use App\Interfaces\VenueRepositoryInterface;
use Illuminate\Http\Request;
class VenueController extends Controller
{
protected $venueRepository;
public function __construct(VenueRepositoryInterface $venueRepository)
{
$this->venueRepository = $venueRepository;
}
public function index()
{
$this->venueRepository->find(1);
return view( 'venue');
}
}
VenueRepositoryInterface.php
<?php
// app/Repositories/Contracts/VenueRepositoryInterface.php
namespace App\Interfaces;
interface VenueRepositoryInterface
{
public function find($id);
public function findBy($att, $column);
}
?>
VenueRepository.php
<?php
// app/Repositories/venueRepository.php
namespace App\Repositories;
use App\Interfaces\VenueRepositoryInterface;
use App\Venue;
class VenueRepository implements VenueRepositoryInterface
{
protected $venue;
public function __construct(Venue $venue)
{
$this->venue = $venue;
}
public function find($id)
{
return 2;
}
public function findBy($att, $column)
{
return $this->venue->where($att, $column);
}
}
?>
UPDATE
I have modified my test based on the below comments, but this is now failing with the following
Mockery\Exception\InvalidCountException : Method find(<Any Arguments>) from Mockery_0__VenueRepositoryInterface should be called
exactly 1 times but called 0 times.
My test I am attempting is
Given I request the venue when i visit the venue url then the find method is invoked and 2 is returned.
<?php
namespace Tests\Unit;
use \Mockery;
use Tests\TestCase;
class VenueControllerTest extends TestCase
{
protected $venueRepositoryInterface;
protected $mock;
public function setUp()
{
parent::setUp();
}
public function tearDown()
{
Mockery::close();
}
public function testControllerIndex()
{
$mock = Mockery::mock('VenueRepositoryInterface')->shouldReceive('find')->once()->andReturn(2);
$this->app->instance('VenueRepositoryInterface',$mock);
$response = $this->call('GET','venue');
$this->assertEquals(200, $response->status());
}
}
**UPDATE 2 **
I have now changed the test to follow what has been suggested, this is now working. Oddly it won't work without the assert equals at the end.
**public function testControllerIndex()
{
$venue = new Venue();
$mock = Mockery::mock('App\Interfaces\VenueRepositoryInterface');
$mock->shouldReceive('find')->once()->with(1)->andReturn($venue);
$this->app->instance('App\Interfaces\VenueRepositoryInterface',$mock);
$response = $this->call('GET', 'venue');
$this->assertEquals($response->getStatusCode(), 200);
}**