Dependency Injection na prostym przykładzie w PHP

Cześć! Dzisiaj na tapecie wzór projektowy wstrzykiwanie zależności. Co znajdziesz w tym wpisie:

Czym jest wstrzykiwanie zależności?

Jest to przekazywanie potrzebnej zależności poprzez argument zamiast tworzenia jej. Zanim poznałem DI, miałem zwyczaj pisać kod który w locie tworzył sobie potrzebne zależności. Przykład z życia wzięty:

Jak byś przetestował tą klasę? Ja widzę tylko jedną opcję:

  1. Tworzysz nową instancję,
  2. Za jej pomocą wgrywasz plik na S3,
  3. Weryfikujesz czy plik został wgrany na S3.

Skomplikowane prawda? Wynika to z faktu że klasa jest silnie (wręcz nierozerwalnie) powiązana z klasą klienta S3. Nie możemy przekazać imitacji klienta. To powoduje następujące konsekwencje:

  • nie da się napisać testu jednostkowego – test jest integracyjny,
  • testowanie wymaga połączenia sieciowego oraz poprawnej konfiguracji S3,
  • takie test będzie trwał dużo dłużej niż prosty test jednostkowy.

Jak rozwiązać ten problem? Użyj wstrzykiwania zależności!

Jak je zaimplementować?

Tej klasie do działania potrzebna jest instancja klienta S3. Przekażę ją przez argument konstruktora:

Alternatywną opcją jest użycie settera. Dzięki temu podejściu możemy w łatwy sposób przekazać właściwą instancję klienta S3. Prawdziwą w środowisku produkcyjny a w środowisku testowym imitację.

Implementacja testu w PHPSpec:

Cały test jest bardzo prosty do napisania, trwa 93ms 🙂

Jakie ma plusy i minusy?

Zacznę od plusów:

  • ułatwia a czasem wręcz umożliwia pisanie testów jednostkowych,
  • rozluźnia powiązanie między klasami, w przypadku użycia interfejsów czy klas abstrakcyjnych powiązanie jest jeszcze słabsze,
  • wyprowadzania logikę tworzącą obiekty w inne miejsca

Minusy:

  • gdzieś te obiekty trzeba stworzyć, w prostych projektach tworzę klasy fabryki, w większych zdecydowanie polecam użycie kontenera wstrzykiwania zależności,
  • kod może się wydawać trudniejszy do zrozumienia.

Linki

Kahlan – PHP test framework – dla wolności, prawdy i sprawiedliwości

TDD

Czyli coś co chyba każdy z nas robi – a przynajmniej powinien! Kto słyszał o PHPUnit? Albo o PHPSpec? A może Codeception? To dobre i sprawdzone narzędzia które mają jednak swoje minusy. Dzisiaj chcę wam zaprezentować całkiem świeże narzędzie – Kahlan.

Co to kurcze jest?

Jest to kolejny framework do pisania testów. Czym się różni od poprzednich? Na pewno składnią. Czy znacie RSpec albo jasmine? Tutaj mamy bardzo podobną implementację dla PHP, a więc używamy describe-it. Jest to cholernie wygodne i łatwe do zrozumienia. Chcecie przykład*?

Czytaj dalej Kahlan – PHP test framework – dla wolności, prawdy i sprawiedliwości

ESLint – install and config – PhpStorm/WebStorm and git pre commit hook

Hello there! It’s been awhile since last post. Sorry 🙁

Let’s talk about JavaScript linting. If you don’t know what is it – go to wikipedia.

Quick Introduction

Currently we have four linting tools available:

Czytaj dalej ESLint – install and config – PhpStorm/WebStorm and git pre commit hook

Running and debugging Karma in PhpStorm / WebStorm

Hello!

Recently I wrote a post about configuring the Karma with RequireJS and PhantomJS (http://damian.dziaduch.pl/2015/09/12/karma-among-with-jasmine-requirejs-and-phantomjs/).

Today I’d like to move on and use the Karma inside the IDE instead of terminal. Before we start make sure you have installed & enabled Karma plugin and JavaScript debugger plugin in PhpStorm. I’m going to work on my previous example.

Czytaj dalej Running and debugging Karma in PhpStorm / WebStorm

Karma among with Jasmine, RequireJS and PhantomJS

This time something about JavaScript. Everybody likes JavaScript :P.

I’d like to write quick guide how to set up working tests environment.

First, what we need:

Let get all required things by NPM. Create a package.json with content:

Now run the command:

Great. We have now all required dependencies.

Next thing is to configure Karma. There are two ways of doing this, manually by creating a karma config file or using karma creator (karma init command). I prefer doing it manually. Create a new file and name it karma.conf.js. Here’s my file with comments:

Basically what you need to change is basePath and files / exclude. But that’s not all. We need to create another file which will run asynchronous our test with RequireJS. Let’s place this file in the tests and name it main.js. This is the only file which is included by karma. Content of the file:

Variable window.__karma__.files comes from karma.conf.js files section. We need to filter them as we want to require only tests files. The source files will be declared as dependencies of each test file.

Let’s create a example test file tests/exampleSpec.js and put in it:

We are defining a spec which has source file as a dependency. RequireJS injects it’s to our spec and we can now test it with Jasmine. How cool is that?

Let’s define our example via src/example.js:

The last thing which need to be done is to export the variable which will tell Karma where PhantomJS binary is:

Now let’s run Karma:

Finally you should see something like this:

karma

If you have any problems with PhantomJS – maybe you need to install some libs required by it. Check it’s website for more info. Other solution is to try different browser – Chrome, Firefox etc. But this can’t be done via SSH… 🙂

Any problems, suggestions, feel free to comment.

 

PHP built in server and sessions

Hi!

Today I was struggling with Codeception tests. I’m working on Vagrant machine which has Apache2 installed.

Thing is that to view the page on my host machine I’m utilising Apache. But in the acceptance tests I’m using PHP built in server. To be specific https://github.com/tiger-seo/PhpBuiltinServer is used. It allows to run server as tests are running and destroy it at the end. It also supports many options.

Acceptance tests were broken. The Tester could not login. After some investigation I found that the issue was caused by read/write permissions for session. By default my Vagrant tries to store the session files in the /var/lib/php/session. As I opened my project in Apache earlier the permissions were given for it. There are two options to solve this:

  • change the path for session files,
  • change the permissions for the current path.

I choose first option. To be specific I changed it only for server used by tests. The extension allows to specify custom .ini file. So my file tests/php.ini look like this:

Also here’s part of my codeception.yml file:

Now session are working in tests 🙂

 

Cheers!