# Testing

## Testing

Testing is an important part of the work as a developer. We want to make sure that the code we write works the way we expect it to work. And that this code will keep working that way in the future.

We use several tools for testing, but the most notable libraries are:

* Jest
* Testing Library (React)

We also use a few other tools for mocking and stubbing, like Nock.&#x20;

{% hint style="info" %}
There are countless of articles on testing, stubbing and mocking. I suggest reading a couple of them online to understand these concepts
{% endhint %}

### What do test?

We mainly test two things:

* The way our React-components work (with the help of Jest and Testing Library)
* Utility functions and helpers (Jest)

Please keep in mind that we never make requests to the outside world when testing. That means you will have to mock any HTTP-calls (for which you can use Knock). By using knock you can create a fake-response in the shape of a real-life response. That fake-response will then get returned every time you attempt to make an HTTP-request to a certain endpoint.&#x20;

{% hint style="info" %}
In general we test the happy path. In some occasions you might want to test the unhappy path too when it is likely to occur often
{% endhint %}

### Where do we put our tests?

We often put our UI-tests (with Testing Library) in a folder named \_\_tests\_\_ in the root of the package that we are working on.\
\
It can pay off to put the utility-tests in the same folder as the file that contains the utility. So:

```
utility.js
utility.test.js
some-tools.js
some-tools.test.js
```

### How to write tests

Tests consist of a describe-block (possibly nested) and it-blocks. Inside the it-blocks we put our assertions using the expect-function.

```javascript
describe("WHAT", () => {
  describe("WHEN", () => {
    it("WHAT DO WE EXPECT", () => {});
  });
});

// Example:

describe("formatEuro", () => {
  beforeAll(() => {
    // do something here before all tests run
  });
  
  beforeEach(() => {
    // do something here before each test 
  });
  
  describe("when passing a number", () => {
    it("returns a formatted amount in euros", () => {
      expect(formatEuro(100)).toEqual("€ 100,00")
    });
  });
  
  describe("when passing a string ", () => {
    describe("and the string resembles a number", () => {
      it("returns a formatted amount in euros", () => {
        expect(formatEuro("100")).toEqual("€ 100,00")
      });
    })
  });
  
  describe("when passing it nothing", () => {
    it("throws an error", () => {
      expect(() => formatEuro(undefined)).toThrowError();
    });
  });
});

```

{% hint style="info" %}
Remember to test the outcome, not the implementation. We should be able to change the implementation in a later stage, and the tests should still succeed if the new implementation is correct&#x20;
{% endhint %}
