Been going in circles for a while, and I hope somebody can get me going again...
I'm writing phpunit unit tests for a Laravel 4.2 controller function but get an error telling me that a function doesn't exist on my mock object.
Here's the controller:
use My\Storage\Cond\CondInterface as Cond;
class CondRuleController extends \BaseController {
protected $rule;
public function __construct(Cond $rule)
{
$this->rule = $rule;
}
public function store()
{
// Limit input input
$post = Input::only('A','B','C');
// Calculate and add another value
$post['D'] = $this->rule->nextOrder($post['A']);
// Try to create the rule or throw error
$this->rule = $this->rule->create($post);
if($this->rule->errors) throw new Exception('nope!');
return View::make('success_view');
}
And the interface:
namespace My\Storage\Cond;
interface CondInterface {
public function nextOrder($value);
public function create($data);
...
}
And the Eloquent repository (bound to interface in a Service Provider not shown here):
namespace My\Storage\Cond;
use My\Storage\Cond\CondInterface;
use Cond;
class CondEloquentRepository implements CondInterface {
protected $rule;
public function __construct(Cond $rule)
{
$this->rule = $rule;
}
public function nextOrder($value)
{
$max = $this->rule->whereValue($value)->max('order');
return (empty($max)) ? 1 : $max + 1;
}
// Use Eloquent create() method
public function create($post)
{
return $this->rule->create($post);
}
...
}
Cond is a pretty standard Eloquent model.
And my test:
class CondRuleControllerTest extends TestCase {
public function setUp()
{
parent::setUp();
$this->mock = Mockery::mock("My\Storage\Cond\CondInterface")->makePartial();
$this->controller = new CondRuleController($this->mock);
// Set up passing defaults
$this->input = array('A' => 'red', 'B' => 'blue','C' => 'green');
Input::replace($this->input);
// Extended results following nextOrder
$this->create_data = array('A' => 'red', 'B' => 'blue','C' => 'green', 'D' => 1);
}
public function tearDown()
{
Mockery::close();
}
public function testStoreOK()
{
$this->mock->shouldReceive('nextOrder')
->once()
->with('red')
->andReturn(1);
$this->mock->shouldReceive('create')
->once()
->with($this->create_data)
->andReturn($this->mock);
View::shouldReceive('make')->once()->with('success_view');
$this->controller->store();
}
When I run this, then I get the following error:
1) CondRuleControllerTest::testStoreOK
BadMethodCallException: Method Mockery_0_My_Storage_Cond_CondInterface::create() does not exist on this mock object
I'm confused why create() doesn't appear to be mocked correctly, but nextOrder() does. Perhaps it is clashing with Eloquent's create()?
On a seperate (unrelated) note, I found that removing the with() statement in the second shouldReceive() makes the test pass, but with zero assertions.
Any suggestions gratefully received!
Aucun commentaire:
Enregistrer un commentaire