【发布时间】:2018-03-14 20:37:15
【问题描述】:
对于 laravel 5.1 中的单元测试,我正在尝试测试客户端模型的级联删除功能,该功能设置了递归标志,还应该删除与客户端关联的所有用户。 我想使用模拟用户并仅在调用用户的删除功能时进行测试,因此我不必使用数据库,并且将来将相同的原理应用于其他测试。
目前测试失败,因为我无法找到一种方法让客户端模型在不触发查询的情况下检索关联用户。 我想我需要模拟客户端的 hasMany 关系定义函数,但我还没有找到方法。
客户端模型:
class Client extends Model
{
protected $table = 'clients';
protected $fillable = [];
public function casDelete($recursive = false){
if($recursive) {
$users = $this->users()->get();
foreach($users as $user) {
$user->casDelete($recursive);
}
}
$this->delete();
}
public function users(){
return $this->hasMany('App\User');
}
}
用户模型:
class User extends Model implements AuthenticatableContract, CanResetPasswordContract
{
use Authenticatable, CanResetPassword;
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = ['name', 'email', 'password', 'client_id'];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = ['password', 'remember_token'];
public function casDelete($recursive = false){
$this->delete();
}
public function client(){
return $this->belongsTo('App\Client');
}
}
测试:
class ClientModelTest extends TestCase
{
use DatabaseTransactions;
function testCasDelete(){
$client = factory(Client::class)->create();
$user = factory(User::class)->make(['client_id' => $client->id]);
$observer = $this->getMock('user');
$observer->expects($this->once())->method('casDelete');
$client->casDelete(true);
}
}
【问题讨论】:
-
不能使用工厂制作User,需要给
$client关联一个mock用户。 -
@apokryfos 好的,如何做到这一点?我试过
\Mockery::mock('Client')->shouldReceive('users')->andReturns($mockedUser)之类的东西,但不会返回给实际测试的客户端 -
$users = $this->users()->get();无论如何都会运行数据库查询。您还需要模拟客户端,特别是users()方法应该返回另一个模拟,其get()方法返回模拟用户。
标签: php laravel mocking phpunit