所以我正在学习如何测试。首先,我试图理解并遵循SOLID原则,因为我认为这有助于稍后进行测试。
因此,我的UserController
store
方法充斥着许多代码,例如授权用户,加密密码,触发事件等等。
因此,在我的存储库中使用create
方法后,它看起来很干净,只有一个输入和输出的责任,看起来像这样:
public function store(CreateUserRequest $request)
{
$user = $this->user->create($request->all());
return response()->jsend(
$data = $user,
$presenter = $this->presenter,
$status = 'success',
$message = 'Resource Created Successfully',
$code = 201
);
}
注意:$this->user
实际上是存储库实例,而不是模型本身。
我的用户存储库的create method
如下所示:
public function create(array $data)
{
// $this->authorize('store', $this->model);
$data['password'] = bcrypt($data['password']);
$user = $this->model->create($data);
event(new UserWasCreated($user));
return $user;
}
我写的测试用例如下:
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use Uppdragshuset\AO\Tenant\Repositories\EloquentUserRepository;
use Uppdragshuset\AO\Tenant\Models\User;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Uppdragshuset\AO\Tenant\Events\UserWasCreated;
class EloquentUserRepositoryTest extends TestCase
{
protected $user;
public function setUp()
{
parent::setUp();
$this->userRepo = new EloquentUserRepository;
}
public function tearDown()
{
Mockery::close();
}
public function test_create_a_new_user()
{
// $mock->shouldReceive('authorize')->once()->andReturn('');
$user = factory(User::class)->make([
'password' => 'password'
])->getAttributes();
$this->expectsEvents(UserWasCreated::class);
$user = $this->userRepo->create($user);
}
}
所以我能够执行$this->expectsEvents(UserWasCreated::class);
之类的事情,而事件实际上并没有出现在redis数据库中。所以我理解嘲讽的基本知识。
但请注意我在authorize
方法中注释了create
方法以及在测试中对它的模拟,因为当我尝试模拟authorize
方法时,我尝试过很多东西,但不是很多,对我来说有意义,因为authorize
方法来自trait
而不是class
所以如何模拟特征,如果我取消注释authorize
create
方法,它给我一个错误,说用户没有被授权是有意义的,因为根本没有授权。那么如何模仿这一点,我是否正确地做了这一切,或者我是否正在创造像业余爱好者这样的愚蠢测试?
更新
我甚至在测试中试过这个:
$mock = Mockery::mock(Gate::class);
$this->app->instance(Gate::class, $mock);
$mock->shouldReceive('authorize')->once();
但没有运气。