Unit test промежуточное ПО Laravel

Я пытаюсь написать модульные тесты для моего промежуточного программного обеспечения в Laravel. Кто-нибудь знает учебник или есть пример этого?

Я писал много кода, но должен быть лучший способ проверить метод дескриптора.

Ответ 1

Используя Laravel 5.2, я тестирую свое промежуточное программное обеспечение, передавая ему запрос со вводом и закрытием с утверждениями.

Итак, у меня есть промежуточное программное обеспечение class GetCommandFromSlack, которое анализирует первое слово поля text в моем сообщении (текст из команды Slack slash) в новое поле под названием command, а затем изменяет поле text чтобы больше не иметь этого первого слова. Он имеет один метод со следующей подписью: public function handle(\Illuminate\Http\Request $request, Closure $next).

Мой тестовый пример выглядит следующим образом:

use App\Http\Middleware\GetCommandFromSlack;
use Illuminate\Http\Request;

class CommandsFromSlackTest extends TestCase
{
  public function testShouldKnowLiftCommand()
  {
    $request = new Illuminate\Http\Request();
    $request->replace([
        'text' => 'lift foo bar baz',
    ]);
    $mw = new \App\Http\Middleware\GetCommandFromSlack;
    $mw->handle($request,function($r) use ($after){
      $this->assertEquals('lift',       $r->input('command'));
      $this->assertEquals('foo bar baz',$r->input('text'));
    });
  }
}

Я надеюсь, что это поможет! Я попытаюсь обновить это, если у меня будет более сложное промежуточное программное обеспечение.

Ответ 2

Чтобы действительно проверить класс промежуточного ПО, вы можете:

public function testHandle()
{

    $user = new User(['email'=>'...','name'=>'...']);
    /**
     * setting is_admin to 1 which means the is Admin middleware should 
     * let him pass, but oc depends on your handle() method
     */
    $user->is_admin = 1;        
    $model = $this->app['config']['auth.model'];
    /**
     * assuming you use Eloquent for your User model
     */
    $userProvider = new \Illuminate\Auth\EloquentUserProvider($this->app['hash'], $model);

    $guard = new \Illuminate\Auth\Guard($userProvider, $this->app['session.store']);
    $guard->setUser($user);

    $request = new \Illuminate\Http\Request();        
    $middleware = new \YourApp\Http\Middleware\AuthenticateAdmin($guard);        

    $result = $middleware->handle($request, function(){ return 'can access';});
    $this->assertEquals('can access',$result);

}

Ответ 3

Я думаю, что лучшим решением является просто проверка того, что произошло после промежуточного ПО. Например, промежуточное ПО для проверки подлинности:

<?php namespace App\Http\Middleware;

use Closure;
use Illuminate\Contracts\Auth\Guard;

class Authenticate {

    /**
     * The Guard implementation.
     *
     * @var Guard
     */
    protected $auth;

    /**
     * Create a new filter instance.
     *
     * @param  Guard  $auth
     * @return void
     */
    public function __construct(Guard $auth)
    {
        $this->auth = $auth;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($this->auth->guest())
        {
            if ($request->ajax())
            {
                return response('Unauthorized.', 401);
            }
            else
            {
                return redirect()->guest('auth/login');
            }
        }

        return $next($request);
    }

}

И моя тестовая единица:

<?php

class AuthenticationTest extends TestCase {

    public function testIAmLoggedIn()
    {
        // Login as someone
        $user = new User(['name' => 'Admin']);
        $this->be($user);

        // Call as AJAX request.
        $this->client->setServerParameter('HTTP_X-Requested-With', 'XMLHttpRequest');
        $this->call('get', '/authpage');

        $this->assertEquals(200, $response->getStatusCode());
    }

}

Я бы сделал это таким образом.

Ответ 4

Я работал над промежуточным ПО локализации, которое устанавливает локаль приложения на основе сегмента URI, например. http://example.com/ar/foo должно установить локальное приложение на арабский. Я в основном издевался над объектом Request и тестировался как обычно. Вот мой тестовый класс:

use Illuminate\Http\Request;
use App\Http\Middleware\Localize;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class LocalizeMiddlewareTest extends TestCase
{
    protected $request;
    protected $localize;

    public function setUp()
    {
        parent::setUp();

        config(['locale' => 'en']);
        config(['app.supported_locales' => ['en', 'ar']]);

        $this->request = Mockery::mock(Request::class);

        $this->localize = new Localize;
    }

    /** @test */
    public function it_sets_the_app_locale_from_the_current_uri()
    {
        $this->request->shouldReceive('segment')->once()->andReturn('ar');

        $this->localize->handle($this->request, function () {});

        $this->assertEquals('ar', app()->getLocale());
    }

    /** @test */
    public function it_allows_designating_the_locale_uri_segment()
    {
        $this->request->shouldReceive('segment')->with(2)->once()->andReturn('ar');

        $this->localize->handle($this->request, function () {}, 2);

        $this->assertEquals('ar', app()->getLocale());
    }

    /** @test */
    public function it_throws_an_exception_if_locale_is_unsupported()
    {
        $this->request->shouldReceive('segment')->once()->andReturn('it');
        $this->request->shouldReceive('url')->once()->andReturn('http://example.com/it/foo');

        $this->setExpectedException(
            Exception::class,
            "Locale `it` in URL `http://example.com/it/foo` is not supported."
        );

        $this->localize->handle($this->request, function () {});
    }
}

И вот мой класс Middleware:

namespace App\Http\Middleware;

use Closure;

class Localize
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  integer  $localeUriSegment
     * @return mixed
     */
    public function handle($request, Closure $next, $localeUriSegment = 1)
    {
        $locale = $request->segment($localeUriSegment);

        if (in_array($locale, config('app.supported_locales')))
        {
            app()->setLocale($locale);
        }
        else
        {
            abort(500, "Locale `{$locale}` in URL `".$request->url().'` is not supported.');
        }

        return $next($request);
    }
}

Надеюсь, что помогает:)