BDD is a technique used at story level and spec level. The technique is to first describe the behaviour of an object you are about to write. Next you write just enough code to meet that specification.
Sounds interesting. Let’s give it a shot, shall we?
Hands on PHPSpec - PHPCon Poland 2016. Hands on PHPSpec workshop, PHPCon Poland September 30th 2016. SpecBDD Framework for PHP. Contribute to phpspec/phpspec development by creating an account on GitHub. See full list on laravel-news.com. Phpspec is the exact same for unit tests. Instead of just writing tests and getting them to pass, phpspec makes you think about the design, behavior and purpose of your PHP classes first. And as a nice by-product, you get unit tests. Great - let's move onto some buzzwords. Composer require karriere/phpspec-matchers To be able to use the matchers you need to add the following definition to your phpspec.yml extensions: Karriere PhpSpecMatchers Extension:.
We’re going to start off creating a fresh project using the Symfony Skeleton, and installing PHPSpec.Using the symfony binary, creating a new project is very straight forward. You can follow along if you like.
I like motorcycles, so let’s use that as our subject.
First of all, we’ll need to create the specification to describe our motorcycle class.Luckily, PHPSpec can help us create this file.
PHPSpec will now generate a specification for the
App/Motorcycle class in the
tests/spec directory.The generated file will look like this:
As you can see, this doesn’t describe much. The method
it_is_initializable will just check if the Motorcycle class can be initialized. Currently, we haven’t created that class yet - so running PHPSpec should give us an error.We can run the tests using the following command.
As expected, PHPSpec tells us our code is broken. It also suggests creating the class for us, so we’ll accept that offer.Note: You can disable the suggestions by passing the
--no-code-generation option when running the command.We’ve now got our base class:
This also means our test should pass, so let’s try!
Great. As you noticed, PHPSpec helped us out quite a bit here. As you’ll see in the rest of this post, PHPSpec can actually generate quite a lot of stuff to help us.Let’s start adding some methods to our Motorcycle class.
First custom behaviour
We’re going to start off with a simple behaviour.For example, we want to make sure our motorcycle is currently running. We can add a fairly simple test for that to our specification.
Strange. We’re calling the
isRunning() method, but it doesn’t exist in our specification. Surprise! There’s a catch. The
$this keyword in the specification doesn’t refer to the spec itself, but to our Motorcycle class. Therefore, PHPSpec will try calling the function on the Motorcycle class.
We’re also chaining the
shouldReturn function. This is a PHPSpec Matcher. Matchers in PHPSpec are similar to assertions in PHPunit, and describe how an object should behave. There’s a lot of matchers available, to match your usecase.
We can try running our test again.
The failing test is obviously the
it_is_running test.All tests green looked way better, so let’s fix it.In our Motorcycle class, we’ll add a method
isRunning() that returns true.
This immediately fixes our tests, as expected.
Slightly more advanced testing (Stubs)
Class methods often require arguments to perform actions. Our motorcycle, for example, could have a function
canRide(Rider $rider), that returns whether or not the rider can ride the motorcycle.To test this, we’ll add the following stub:
Our tests are failing, but as you can see, PHPSpec suggests generating an interface
AppRider.Perhaps we’ll want to add different types of people later, so using an interface makes sense. Let’s say no for now, and replace our Rider typehint with PersonInterface. This way we can make sure our naming is nice and clean.
We’ll run the PHPSpec command again, and allow it to generate the interface for us.Okay, so now that we’ve got the interface, will our test pass?
Obviously not. Our interface doesn’t even have the
hasMotorcycleLicense() method signature.Again, PHPSpec suggests generating it, so let’s agree.
Sweet! We’ve now got our interface ready.Note that in the code snippet below, I did add the
bool return type myself.
Phpspec Vs Phpunit
All we need to do now, is implement the
canRide method in the Motorcycle class.
When we try running PHPSpec again, we can once again see that all our tests are green!
The functionalities I’ve shown here are just the tip of the iceberg.Perhaps I can do a follow-up with some more advanced examples, but for now, this is the end.I hope you’ve enjoyed this read, and hopefully you’ve even learned something along the way. I highly suggest that you check out the PHPSpec Manual if you’re interested in learning more.
- Symfony 5.1
- PHPSpec 6.2
Mockery is a simple yet flexible PHP mock object framework for use in unittesting with PHPUnit, PHPSpec or any other testing framework. Its core goal isto offer a test double framework with a succinct API capable of clearlydefining all possible object operations and interactions using a humanreadable Domain Specific Language (DSL). Designed as a drop in alternative toPHPUnit’s phpunit-mock-objects library, Mockery is easy to integrate withPHPUnit and can operate alongside phpunit-mock-objects without the Worldending.
In unit tests, mock objects simulate the behaviour of real objects. They arecommonly utilised to offer test isolation, to stand in for objects which donot yet exist, or to allow for the exploratory design of class APIs withoutrequiring actual implementation up front.
The benefits of a mock object framework are to allow for the flexiblegeneration of such mock objects (and stubs). They allow the setting ofexpected method calls and return values using a flexible API which is capableof capturing every possible real object behaviour in way that is stated asclose as possible to a natural language description.
Function Return Object In Phpspec
Ready to dive into the Mockery framework? Then you can get started by readingthe “Getting Started” section!
The reference contains a complete overview of all features of the Mockeryframework.
Learn about Mockery’s configuration, reserved method names, exceptions…
Want to learn some easy tips and tricks? Take a look at the cookbook articles!