# Stack kata

### Objective

* Create production code from test
* Start from assertions

![](https://1936518372-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAffO8xa1ZWmgZvfeK2%2F-MRizn-izcas0CKDCJW7%2F-MRizretsxH2i6LhX3KZ%2Fimage.png?alt=media\&token=4a94b910-f985-4489-bab1-84dc8a32cdb7)

## Connection - 10'

What are the key principles to write good unit tests ?

## Concepts - 10'

{% hint style="info" %}
Tip for deciding the first test to write: The simplest possible.
{% endhint %}

* Red, Green, Refactor
  * Add a test
  * Run all tests and see if the new one fails - Red
  * Write the minimum amount of code to pass the failing test -&#x20;
  * Run tests - Green
  * Refactor code - Blue&#x20;
  * **Repeat**
* TDD Golden Rule
  * **Do not write any production code until you have a failing test that requires it**
* Arrange, Act, Assert
  * Arrange :
    * Setup everything needed for the testing code
    * Data initialization / mocks
  * Act :
    * Invoke the code under test / behavior
  * Assert :
    * Specify the pass criteria for the test

Define a test checklist for your team :

![](https://1936518372-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAffO8xa1ZWmgZvfeK2%2F-MRj0BkeOH0rFXchqm2P%2F-MRj0GhkJKXdZEdVLJMe%2Fimage.png?alt=media\&token=6ae3ed4f-470f-4270-a4a0-1b8a447dd8b0)

## Concrete Practice - 25'

* In pair, implement a Stack class with the following public methods by  using TDD :

```
void push(Object object)
Object pop()
```

* Stack should throw an exception if popped when empty
* Start by writing your assertions

#### When you use TDD :

* Split your screen
  * Your tests at the left
  * Your production code at the right

![](https://1936518372-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAffO8xa1ZWmgZvfeK2%2F-MRj1Q75EFxAi0Bf9BK6%2F-MRjCok7eTqUogUY0R8K%2Fimage.png?alt=media\&token=22654878-1d8e-4270-837a-60f16bac2b12)

#### Questions to ask :

* ***What is the value to test the push ?***
  * Do not change your production code encapsulation for testing purpose
* Often developers want to inherit from ArrayList or another types of collection
  * Ask them Why
  * Remind them that the purpose of TDD is also to avoid writing unnecessary code
    * In the exercise, is it required to have a Count function on the Stack for example ?

After 20' of coding ask them to demonstrate what has been written

Here is a solution : <https://github.com/ythirion/stack-kata>

{% tabs %}
{% tab title="stack\_should" %}

```java
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.EmptyStackException;

public class stack_should {
    private final Object object1 = new Object();
    private final Object object2 = new Object();

    private Stack stack;

    @BeforeEach
    public void init() {
        stack = new Stack();
    }

    @Test
    public void raise_an_exception_when_popped_and_empty() {
        Stack emptyStack = new Stack();
        Assertions.assertThrows(EmptyStackException.class, emptyStack::pop);
    }

    @Test
    public void pop_the_last_object_pushed() {
        stack.push(object1);
        Assertions.assertEquals(object1, stack.pop());
    }

    @Test
    public void pop_objects_in_the_reverse_order_they_were_pushed()
    {
        stack.push(object1);
        stack.push(object2);

        Assertions.assertEquals(object2, stack.pop());
        Assertions.assertEquals(object1, stack.pop());
    }
}

```

�Ask to the participants what do they think about the naming of the tests.
{% endtab %}

{% tab title="Stack" %}

```java
import java.util.ArrayList;
import java.util.EmptyStackException;

public class Stack {
    private final ArrayList<Object> stack;

    public Stack() {
        stack = new ArrayList<>();
    }

    public Object pop() {
        if(stack.isEmpty()) {
            throw new EmptyStackException();
        }
        var lastElement = stack.get(stack.size() - 1);
        stack.remove(lastElement);

        return lastElement;
    }

    public void push(Object element) {
        stack.add(element);
    }
}
```

{% endtab %}
{% endtabs %}

## Conclusion - 5'

Note the main thing you want to remember about this session on a Sticky Note

### Resources

* [Programming with GUTs by Kevlin Henney](https://www.youtube.com/watch?v=azoucC_fwzw\&ab_channel=BuildStuff)
* [Test Driving Algorithms by Sandro Mancuso](https://codurance.com/videos/2014-12-05-test-driving-algorithms/)

![](https://1936518372-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MAffO8xa1ZWmgZvfeK2%2F-MRjVDignWvILN508F3k%2F-MRjVSpXBxAQyFERUC-i%2Fimage.png?alt=media\&token=d81c73e1-c968-440f-8178-5c97b1f6c9ef)
