如何在Laravel 5中模拟特征并在存储库上测试创建方法?

时间:2016-03-22 18:49:43

标签: php unit-testing laravel testing laravel-5

所以我正在学习如何测试。首先,我试图理解并遵循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();

但没有运气。

0 个答案:

没有答案