TDD в Laravel с использованием phpunit для разработки REST Api
Начните работу с TDD в Laravel, используя phpunit для разработки REST Api. В качестве примера мы рассмотрим создание API с использованием подхода TDD, чтобы позволить пользователю обновлять свой профиль.
TDD подход
Идея подхода TDD заключается в том, чтобы сначала создать тестовый пример, прежде чем писать фактический код. Таким образом, написание кода API становится легким, если вы уже поняли все, что вы будете делать в API во время написания тестового примера.
После того, как у вас есть тестовый пример, после каждого изменения в API вы можете проверить, работает ли ваш API должным образом, запустив тестовый пример.
Переменные среды
Если вы посмотрите на phpunit.xml. Вы увидите переменные среды, определенные следующим образом.
<php> <server name="APP_ENV" value="testing"/> <server name="BCRYPT_ROUNDS" value="4"/> <server name="CACHE_DRIVER" value="array"/> <server name="DB_CONNECTION" value="sqlite"/> <server name="DB_DATABASE" value=":memory:"/> <server name="MAIL_MAILER" value="array"/> <server name="QUEUE_CONNECTION" value="sync"/> <server name="SESSION_DRIVER" value="array"/> </php>
Эти переменные среды используются при выполнении тестовых случаев. Laravel автоматически установит переменные среды, определенные в этом файле.
Здесь следует отметить, что мы используем в памяти базу данных sqlite. Преимущество использования базы данных в памяти заключается в том, что она автоматически создается в памяти при запуске тестов и автоматически удаляется после завершения тестовых случаев. Это не повлияет на вашу фактическую используемую базу данных. Вы можете настроить эти переменные среды в соответствии с вашими требованиями.
Создание теста
Откройте файл TestCase. Нам нужно будет внести некоторые изменения здесь, чтобы перенести и заполнить базу данных перед тестовым случаем. Для этого переопределите функцию setUp следующим образом.
<?php namespace Tests; use Illuminate\Foundation\Testing\TestCase as BaseTestCase; use Illuminate\Foundation\Testing\WithFaker; abstract class TestCase extends BaseTestCase { use CreatesApplication, WithFaker; protected function setUp(): void { parent::setUp(); $this->artisan('migrate'); $this->artisan('db:seed'); $this->withoutExceptionHandling(); //To get the actual Exception whenever it occurs instead of Laravel handing the exception. } }
Создадим новый тест с помощью команды:
php artisan make:test UserTest
Откройте Tests/Feature/UsersTest.php
Напишите свой первый тестовый пример следующим образом:
<?php namespace Tests\Feature; use App\User; use Tests\TestCase; use JWTAuth; class UsersTest extends TestCase { /** @test */ public function a_user_can_edit_his_profile() { $user = User::first(); $token = JWTAuth::fromUser($user); $attributes = ['name' => $this->faker->name]; $this->patchJson('api/user/profile', $attributes, ['authorization' => "bearer $token"]) ->assertStatus(200); $this->assertDatabaseHas($user->getTable(), array_merge($attributes, [ 'id' => $user->id ])); } }
Здесь мы используем JWT, но вы можете изменить его в соответствии с пакетом, который вы используете для создания токена аутентификации.
Мы используем функцию assertDatabaseHas и передаем имя таблицы и данные, которые должны присутствовать, чтобы проверить, обновлен ли профиль в базе данных.
Теперь, если мы попытаемся запустить, это не удастся, потому что мы еще не создали маршрут API.
Создание роута и контроллера
Сделаем это в api.php
Route::patch('user/profile','UserController@updateProfile');
Создайте новый контроллер с помощью команды:
php artisan make:controller UserController
Напишите функцию updateProfile в UserController , чтобы позволить пользователю редактировать свой профиль следующим образом:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class UserController extends Controller { public function __construct() { $this->middleware('auth:api'); } public function updateProfile() { $attributes = request()->validate(['name' => 'required|string']); auth()->user()->update($attributes); return response()->json(["msg" => "Profile successfully updated"]); } }
Запуск теста
Попробуйте запустить тестовый пример еще раз, и на этот раз ваш тестовый пример должен пройти успешно.
Вот и все!
Надеюсь, вы найдете это полезным!