testing with laravel
TRANSCRIPT
![Page 1: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/1.jpg)
Designing for Testability with Laravel
Derek Binkley@DerekB_WI
![Page 2: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/2.jpg)
About Me★Lead Developer at National Conference of
Bar Examiners★PHP and Java Developer★MySQL DBA★Father of Three★Second ever talk
![Page 3: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/3.jpg)
About NCBEExamining Bars?
![Page 4: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/4.jpg)
About NCBENo, developing the bar exam for future lawyers.
Plus, supporting state admission authorities.
![Page 5: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/5.jpg)
What will we cover?
What is built in to Laravel for Unit TestingStrategies that make testing easier
Detailed examples
![Page 6: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/6.jpg)
Unit Tests• Lowest level of testing• Typically done by developer• Crucial to Test Driven Design• Tests a Single Unit of Code and Verifies the
Results.
![Page 7: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/7.jpg)
Why don’t developers test?• Think code will get replaced soon.• Think code is straightforward and won’t break.• Tests are hard to write.• Low perceived benefit.• Don’t understand how to design code for
testability.
![Page 8: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/8.jpg)
Laravel and PHPUnit• PHPUnit Available by default
• Tests saved in Tests directory• Tests should extend TestCase class• Tests should be saved in file named *Test.php• Tests method names should begin with test.
![Page 9: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/9.jpg)
What Does Laravel Provide?• Crawler – Gives us a mock browser/client to
run our controllers.
![Page 10: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/10.jpg)
What Does Laravel Provide?• Additional assertions• ->assertResponseOk();• ->assertResponseStatus($code);• ->assertViewHas($key, $value = null);• ->assertViewHasAll(array $bindings);• ->assertViewMissing($key);• ->assertRedirectedTo($uri, $with = []);• ->assertRedirectedToRoute($name, $parameters = [], $with = []);• ->assertRedirectedToAction($name, $parameters = [], $with = []);• ->assertSessionHas($key, $value = null);• ->assertSessionHasAll(array $bindings);• ->assertSessionHasErrors($bindings = [], $format = null);• ->assertHasOldInput();
![Page 11: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/11.jpg)
Faking Data• https://github.com/fzaninotto/Faker• Allows us to not spend time making up test
data.
![Page 12: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/12.jpg)
Example Form
![Page 13: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/13.jpg)
Example Controller
![Page 14: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/14.jpg)
Test Code – First Try
![Page 15: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/15.jpg)
Problems?• Database is not cleaned up. We could use
seeding in our setup and teardown methods.• Email attempt adds a dependency upon a
network or cloud service.• Testing all the logic of the controller at once
makes problems hard to diagnose.
![Page 16: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/16.jpg)
Laravel Can Help
• Disabling Middleware allows testing only your controller code• Wrapping test in a database transaction helps clean up• Using migrations allows for resetting database to consistent
state.
![Page 17: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/17.jpg)
How we can help ourselves• DRY – Don’t Repeat Yourself – Be Lazy, write code once• Single Responsibility Object – No “Jack of all Trades” Objects• Dependency Injection – Give me what I need to do my job• Keep cyclomatic complexity low – If there is a fork in the road
take it• Law of Demeter – Don’t extend reach too far• Design Patterns – Somebody has already solved our problems
![Page 18: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/18.jpg)
Improving Our Example
• Remove dependency on session
![Page 19: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/19.jpg)
Rerun Test and See Failure
• Remove if (is_numeric(session($user_id)))
![Page 20: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/20.jpg)
Dependency Injection• Pass in the objects you need• Code to interfaces• Avoid creating a “new” object.• Setter Injection v. Constructor Injection• Helps follow Law of Demeter
![Page 21: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/21.jpg)
Arguments Against DI• Our dependencies won’t change• Too complex
![Page 22: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/22.jpg)
Benefits of DI• Can now mock objects while testing• Test our code, not 3rd party libraries• Loose coupling allows for easier upgrades• Built in to Laravel
![Page 23: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/23.jpg)
Let’s try it out• Laravel will inject an instance of a class that is type hinted in a
constructor or method.
• Now we can use our factory anywhere within our controller.
![Page 24: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/24.jpg)
Controller is Much Skinnier
![Page 25: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/25.jpg)
Mock objects allow for easy controller testing
• We create a mock PersonFactory and specify which methods will be called and what they should return.
![Page 26: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/26.jpg)
• Our person creation logic is now moved to a single class (DRY), our controller can now be tested without a database.
• Yet to test our person factory we must still seed and clean up our database.
![Page 27: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/27.jpg)
Repository Pattern• Separate getting the data from the data
object. • Code to an interface to allow for mocking.
![Page 28: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/28.jpg)
Wrapper Around Class• Takes class doing work as parameter• Easy to Mock• Won’t use underlying resources, e.g. API, to
run test.
![Page 29: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/29.jpg)
Mocking a Facade• The Mail class is a Laravel façade so we can
easily mock it like this.
• Laravel takes care of the rest for us.
![Page 30: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/30.jpg)
Resources• http://martinfowler.com/eaaCatalog/tableDataGateway.html• https://www.youtube.com/watch?v=HhwElTL-mdI - Evan Dorn LA Ruby Meetup• https://www.youtube.com/watch?v=X6c11niH-U8 - Chris Hartjes Ski PHP• https://bosnadev.com/2015/03/07/using-repository-pattern-in-laravel-5/• https://github.com/fzaninotto/Faker• http://laravelcoding.com/blog/laravel-5-beauty-testing• https://laravel.com/docs/5.1/testing• http://martinfowler.com/articles/mocksArentStubs.html
![Page 31: Testing with laravel](https://reader035.vdocuments.us/reader035/viewer/2022081422/5871d86f1a28ab423c8b7155/html5/thumbnails/31.jpg)
Thanks• Derek Binkley - @DerekB_WI or [email protected]• Slides are at
http://www.slideshare.net/DerekBinkley/testing-with-laravel
• Feedback on Joind.in at https://joind.in/talk/dc052