From our fourth meetup which was in November. Happy hacking!

The fourth /dev/night was a continuation of the success we had with the third one. Again we had about 20 people at our meetup! Freakin’ Awesome!

A recap of the event

The topic was TDD - again. @stesie23 taught us the things we couldn’t fit in last time.

He talked about “Arrange, Act, Asset” which basically teaches us how we should approach to write tests. Which means you should set up everything first, then execute the action you want to test and finally validate the result.

Next up was the “Red, Green, Refactor” cycle. Essentially you first write your tests with no implementation. The tests turn red. After that, you can implement what you described with your tests. Now your tests should turn green. Now that your code works and is tested you can refactor. Repeat this cycle until you built what you wanted in the first place. One thing I would like to mention: You don’t always have to refactor after each green step, but you definitely should do it at some point!

So there was one topic left. One which you can understand very easily at first, but to fully realize what it means you need to put yourself under certain circumstances. I’m talking about “Baby Steps”. This technique can be overlooked, but it is fundamental. You shouldn’t write tests for an hour and hack your way through the code for 3 hours to implement it eventually. Your “Red, Green” cycle mentioned above shouldn’t take longer than 5 to 10 minutes. If you struggle to implement it you should consider going back to the starting point and trying again.

ProTip: git reset --hard can be your friend.

After that, it was time for a challenge. It was the “Pig Latin Kata” - again. But this time with a twist. You had to get to a working state (green tests) in 2 minutes and commit your progress. If you failed to achieve that your pairing partner had to git reset --hard and it was his turn. This was a really good challenge to get a feeling what the “Baby Steps” principal really is about. Although it wasn’t easy at first it sure was fun.

We did this until we had a break to eat pizza.

Now there was one thing left. The elephant in the room. Mocking. @stesie23 thought us about Dummy Objects, Fake Objects, Stubs, and Mocks. The lines are blurry, but he also showed us how to implement a Stub.

To make it even possible to implement a Stub you shouldn’t use static calls or dependencies in your construct method.

Dependency Injection is the key!

For example:

final class CurrencyCalculator
{
    private $rateService;

    public function __construct(CurrencyRateService $rateService)
    {
        $this->rateService = $rateService;
    }

    public function convert($amount, $fromCurrency, $date)
    {
        $rate = $this->rateService->getRate($fromCurrency, $date);
        return $amount / $rate;
    }
}

So with PHPUnit you could do something like this to get a Stub:

final class CurrencyCalculatorTest extends PHPUnit_Framework_TestCase
{
    public function test_convert()
    {
        $rateService = $this->getMock(CurrencyRateService::class);
        // or: $this->getMockBuilder(CurrencyRateService::class)->getMock();

        $rateService->method('getRate')
                                ->willReturn(1.20);

        $calculator = new CurrencyCalculator($rateService);
        $result = $calculator->convert(96, 'GBP', '2016-09-25');

        $this->assertEquals(80, $result);
    }
}

Or a Mock:

final class CurrencyCalculatorTest extends PHPUnit_Framework_TestCase
{
    public function test_convert()
    {
        $rateService = $this->getMock(CurrencyRateService::class);
        // or: $this->getMockBuilder(CurrencyRateService::class)->getMock();

        $rateService->expects($this->once())
                                ->method('getRate')
                                ->with($this->equalTo('GBP'), $this->equalTo('2016-09-25'))
                                ->willReturn(1.20);

        $calculator = new CurrencyCalculator($rateService);
        $result = $calculator->convert(96, 'GBP', '2016-09-25');

        $this->assertEquals(80, $result);
    }
}

read more here

Okay, so now that we were all on the same page about Mocking it was time for another challenge. So we had to build a “Currency Calculator”. Which really highlighted the techniques of mocking well.

Learnings

Frist we learned that we are on track to appeal to a wider audience. With baby steps to success. :D We want to focus on the meta-topic “professionalism” / “better code quality” in the future which TDD is a part of.

Also, we learned that meetup.com is a valuable platform because we got some new guests that way.

I want to thank @stesie23 for the really good talk and delightfully interesting challenges! Thanks to all who were there! See you next time. ;)

What’s up next

At our next event, I will explain to you what the hell “Software Craftsmanship” is about. Although this hasn’t something to do with TDD directly. It is a movement which is all about learning and steadily improving your professional skills. I think this fits the overall theme.

The ratio of time spent reading (code) versus writing is well over 10 to 1 ... (therefore) making it easy to read makes it easier to write. Robert C. Martin

TL;DR

If you want to approach TDD the right way just arrange, act, assert your tests before you go through the red, green cycle. Don’t forget to take baby steps. Repeat. Refactor. Profit.


git reset --hard is your friend