Kako izraditi Laravel REST API s test-driven razvojem

Poznati je citat Jamesa Grenninga, jednog od pionira u TDD i Agile razvojnim metodologijama:

Ako se ne bavite razvojem temeljenim na testovima, radite razvoj koji se kasnije ispravlja - James Grenning

Danas idemo na Laravelovo putovanje vođeno testovima. Stvorit ćemo Laravel REST API zajedno s autentifikacijom i CRUD funkcionalnošću bez otvaranja Poštara ili preglednika. ?

Napomena: Ovo uputstvo pretpostavlja da razumijete osnovne koncepte Laravela i PHPUnit-a. Ako ste to maknuli s puta? Vozimo se.

Postavljanje projekta

Započnite s izradom novog projekta Laravel sa composer create-project --prefer-dist laravel/laravel tdd-journey.

Dalje, moramo pokrenuti skener za provjeru autentičnosti koji bismo koristili, samo naprijed i php artisan make:authtada pokrenite php artisan migrate.

Zapravo nećemo koristiti generirane rute i poglede. Za ovaj bismo projekt koristili jwt-auth. Dakle, samo naprijed i postavite ga u svojoj aplikaciji.

Napomena: Ako imate pogreške s generatenaredbom JWT- a, možete slijediti ovaj popravak dok ne bude dodan stabilnom izdanju.

Konačno, možete izbrisati ExampleTestu oba tests/Uniti tests/Featuremape tako da se ne ometa naše rezultate testa, a mi smo dobro ide.

Pisanje koda

  1. Započnite postavljanjem vaše authkonfiguracije da koristi JWT upravljački program kao zadani:

Zatim u routes/api.phpdatoteku dodajte sljedeće :

2. Sad kad smo postavili upravljački program, postavite svoj korisnički model na isti način:

Ono što smo učinili je da smo upravo implementirali JWTSubjecti dodali potrebne metode.

3. Dalje, moramo dodati naše metode provjere autentičnosti u kontroler.

Pokrenite php artisan make:controller AuthControlleri dodajte sljedeće metode:

Ovaj je korak prilično naprijed, sve što radimo je dodavanje metoda authenticatei registermetoda na naš kontroler. U authenticatemetodi provjeravamo ulaz, pokušavamo se prijaviti i vraćamo token ako je uspješan. U metodi registra provjeravamo ulaz, stvaramo novog korisnika s ulazom i generiramo token za korisnika na temelju toga.

4. Dalje, na dobar dio. Testiranje onoga što smo upravo napisali. Generirajte ispitne satove pomoću php artisan make:test AuthTest. U novo tests/Feature/AuthTestdodajte ove metode:

Komentari u gornjem kodu prilično opisuju kod. Jedna stvar koju biste trebali primijetiti je kako stvaramo i brišemo korisnika u svakom testu. Cjelokupna poanta testova je da bi oni trebali biti neovisni jedni o drugima i idealno bi trebali biti u bazi podataka.

Sada pokrenite $vendor/bin/phpunitili $ phpunitako ga imate globalno instaliran. Trčanje koje bi vam trebalo dati uspješne tvrdnje. Ako to nije bio slučaj, možete pregledati zapisnike, popraviti i ponovo testirati. Ovo je prekrasan ciklus TDD-a.

5. Sad kad imamo provjeru autentičnosti, dodajmo stavku za CRUD. Za ovaj ćemo vodič koristiti recepte za hranu kao svoje CRUD predmete, jer, zašto ne?

Započnite s izradom naše migracije php artisan make:migration create_recipes_tablei dodajte sljedeće:

Zatim pokrenite migraciju. Sada dodajte model pomoću php artisan make:model Recipei dodajte ovo našem modelu.

Zatim dodajte ovu metodu u usermodel.

6. Sada su nam potrebne krajnje točke za upravljanje našim receptima. Prvo ćemo stvoriti kontroler php artisan make:controller RecipeController. Zatim uredite routes/api.phpdatoteku i dodajte createkrajnju točku.

U kontroler dodajte i metodu stvaranja

Generirajte test značajki pomoću php artisan make:test RecipeTesti uredite sadržaj kao u nastavku:

Kôd je prilično objašnjen. Sve što radimo je stvoriti metodu koja obrađuje registraciju korisnika i generacije tokena, a zatim koristimo taj token u testCreate()metodi. Imajte na umu upotrebu RefreshDatabaseosobine, osobina je Laravelov prikladan način resetiranja baze podataka nakon svakog testa, što je savršeno za naš izvrstan mali projekt.

U redu, za sada sve što želimo potvrditi je status odgovora, samo naprijed i pokrenite se $ vendor/bin/phpunit.

Ako sve bude u redu, trebali biste primiti pogrešku. ?

There was 1 failure:
1) Tests\Feature\RecipeTest::testCreateExpected status code 200 but received 500.Failed asserting that false is true.
/home/user/sites/tdd-journey/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestResponse.php:133/home/user/sites/tdd-journey/tests/Feature/RecipeTest.php:49
FAILURES!Tests: 3, Assertions: 5, Failures: 1.

Gledajući log datoteke, možemo vidjeti krivac je publisheri recipesodnos u Recipei Userklasama. Laravel pokušava pronaći user_idstupac u tablici i koristiti ga kao strani ključ, ali u našoj migraciji postavili smo publisher_idstrani ključ. Sada prilagodite linije kao ispod:

//Recipe filepublic function publisher(){ return $this->belongsTo(User::class,'publisher_id');}
//User filepublic function recipes(){ return $this->hasMany(Recipe::class,'publisher_id');}

A zatim ponovo pokrenite test. Ako sve bude u redu, dobit ćemo sve zelene testove! ?

... 3 / 3 (100%)
...
OK (3 tests, 5 assertions)

Sada još trebamo testirati stvaranje recepta. Da bismo to učinili, možemo utvrditi broj recepata korisnika. Ažurirajte svoju testCreatemetodu kao u nastavku:

Sada možemo nastaviti i ispuniti ostatak naših metoda. Vrijeme je za neke promjene. Prvo, našaroutes/api.php

Dalje, dodajemo metode u kontroler. Ažurirajte svoju RecipeControllernastavu na ovaj način.

Kôd i komentari već dobro objašnjavaju logiku.

Lastly our test/Feature/RecipeTest

Other than the additional test, the only other difference was adding a class-wide user file. That way, the authenticate method not only generates a token, but it sets the user file for subsequent operations.

Now run $ vendor/bin/phpunit and you should have all green tests if done correctly.

Conclusion

Hopefully, this gave you an insight into how TDD works in Laravel. It is definitely a much wider concept than this, one that is not bound to a specific method.

Though this method of development may seem longer than the usual debug laterprocedure, it’s perfect for catching errors early on in your code. Though there are cases where a non-TDD approach is more useful, it’s still a solid skill and habit to get used to.

The entire code for this walkthrough is available on Github here. Feel free to play around with it.

Cheers!