Last time we talked about how your business logic should look. It was a high level overview of the architecture. This time we’ll actually put that into practice and write some code. We’ll be using BDD (Behavior-Driven-Development) to design the application.
We’re going to be using Behat to run these features. So let’s start a new project!
mkdir sample-app; cd sample-app
git init
We’ll use composer to install Behat:
1 2 3 4 5 6 7 8 |
|
And let’s install it:
1 2 3 4 |
|
So where do we start? BDD says we should start from the outside and move our way in. So, we’ll start with some Gherkin. I’ll make up some requirements that you might receive from a product manager:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Now let’s run it:
1
|
|
You’ll see a bunch of undefined steps with some snippet code. Let’s paste these into our context file (features/bootstrap/FeatureContext.php) and rerun behat. Now we’ll see some TODOs! Time to actually write code! We’ll start from the top:
1
|
|
This is going to be a no-op. We don’t need to do anything here, so let’s just remove the PendingException in the step defintion:
1 2 3 4 5 6 |
|
Now that step should be green when we re-run the behat steps. We’ll move on to the next step. Here’s where the real meat will start. Since we are writing our business logic, we’ll start with defining the interface we want to work with, and write the code we wish we had.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
This might be something we would want. Instantiate a new use case class (Account_Registration), and call it’s execute() method with our registration data.
Let’s run this in behat:
1
|
|
Now we are blocked, we have an error in our tests. So let’s make this thing pass:
1 2 3 4 5 6 7 8 9 |
|
Also make sure you require this file in your FeatureContext class.
1
|
|
Now if you run behat, we’ll have the next step green in both scenarios.
Let’s move on to the next step. What do we do here? How do we assert the account was created? Simple. We want to use Dependancy Injection, and inject a repository object into the use case class. The use case will then use that repository to persist the data. We will use a mock object to keep track of this. We don’t want to use the real thing because we don’t care about the database right now (we will later, and we’ll replace this code later). We’ll need to modify our last step definition:
1 2 |
|
Now when we run behat, we’ll get a fatal error about this Mock class not existing. So let’s just create it at the end of the file.
1 2 3 4 5 6 7 8 9 10 11 |
|
And we’ll need to define that interface. Let’s do that in our classes folder:
1 2 3 4 |
|
Make sure you require that file right above the Mock_Account_Repository class defined above. Now we need to assert that our class does what we want. So in our next step definition, we’ll inspect that mock object:
1 2 3 4 5 6 7 8 |
|
Now when you run this, it should fail. So let’s make it pass.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
On to the next step! We want to send an email out to the user after they register. We need to abstract out the email handling, so let’s make a mock class for that too.
1 2 3 4 5 6 7 8 9 |
|
And the interface for this class:
1 2 3 4 5 6 |
|
And let’s add this to the step definition:
1 2 3 4 5 6 7 |
|
You’ll need to modify some previous steps for this. When you are done, you should get an error like:
1
|
|
So we just need to make this pass. Easy:
1 2 3 4 5 |
|
Sweet! Our first scenario passes! You should be able to implement the rest of the second scenario fairly easily.
This concludes our tutorial on creating a basic Interactor class. It doesn’t do much right now, but next time we’ll add in some validation, and do some other fun stuff with phpspec.