问题
say I have two models that extend from Eloquent
and they relate to each other. Can I mock the relationship?
ie:
class Track extends Eloquent {
public function courses()
{
return $this->hasMany('Course');
}
}
class Course extends Eloquent {
public function track()
{
return $this->belongsTo('Track');
}
}
in MyTest, I want to create a mock of course, and return an instance of track, by calling the track property, not the track instance (I don't want the query builder)
use \Mockery as m;
class MyTest extends TestCase {
public function setUp()
{
$track = new Track(array('title' => 'foo'));
$course = m::mock('Course[track]', array('track' => $track));
$track = $course->track // <-- This should return my track object
}
}
回答1:
Since track is a property and not a method, when creating the mock you will need to override the setAttribute
and getAttribute
methods of the model. Below is a solution that will let you set up an expectation for the property you're looking for:
$track = new Track(array('title' => 'foo'));
$course = m::mock('Course[setAttribute,getAttribute]');
// You don't really care what's returned from setAttribute
$course->shouldReceive('setAttribute');
// But tell getAttribute to return $track whenever 'track' is passed in
$course->shouldReceive('getAttribute')->with('track')->andReturn($track);
You don't need to specify the track
method when mocking the Course
object, unless you are also wanting to test code that relies on the query builder. If this is the case, then you can mock the track
method like this:
// This is just a bare mock object that will return your track back
// whenever you ask for anything. Replace 'get' with whatever method
// your code uses to access the relationship (e.g. 'first')
$relationship = m::mock();
$relationship->shouldReceive('get')->andReturn([ $track ]);
$course = m::mock('Course[track]');
$course->shouldReceive('track')->andReturn($relationship);
来源:https://stackoverflow.com/questions/21050435/laravel-4-mockery-mock-model-relationships