Added unit-test and CI to the findBreakURL program!
Published: 2020-11-26 02:43:46

### Should we run the program every time?
After implementing all codes for this program, I need to manually run the program and if there is any bug on there. To see what lines are wrong and what function throws error, I coded `console.log` hundreds of times. This is really TIME CONSUMING!

Now, it is time to introduce unit tests for my program to make the process faster and more reliable. Then, the question is what is the unit tests?

### One test module will make your life so much easier
Test module is only for literally testing your program. However, it focuses on one specific job rather than a whole process. 
Let's imagine, you are baking a cookie. There are many ingredients to be prepared beforehand. How much sugar is needed and what type of flour should be used, something like these. It is hard to check them all at once just before put altogether. The best way is make a check list and check each of them are OK. Likewise, unit test is checking each function or component is passed. 

### JEST is the BEST
There are many test tool like JASMINE, ENZYME and KARMA...BUT They are so much similar. So don't take too much time to choose the tools!

For my project, I used JEST because I have used that before for my react.js project and my prof is using this tool too!

To set up 
`npm i jest --save-dev`
This will make the jest installed as a devDependencies.

### FileRead.test.js
Let's create a test file for file reading. The file reading is essentially reading a file from given path or file name. However, we cannot use the normal file system for our test. We need to somehow create a mock file system.

Thankfully, Jest already has mock file system. For more info please visit the [JEST documentation](https://jestjs.io/docs/en/manual-mocks)

In the `__mocks__/fs.js` file :
```
const fs = jest.createMockFromModule('fs');
...
function __setMockFileData(filename, data) {
    mockFiles = {};
    mockFiles[filename] = data;
}
...
function readFileSync(filename) {
    const data = mockFiles[filename];

    if (data) {
        return data;
    } else {
        throw new Error("invalid file");
    }
}
```
1. `createMockFromModule` will generate a mock filesystem.
2. `__setMockFileData` will receive given filename and put the given value into the correspond filename (acting like the file and data)
3. `readFileSync` is overloaded and performed when the test file is needed to call this function.

Now, this module will generate mock file system. It is time to make a test
```
const { fileRead, readDirectory } = require('./fileRead');

jest.mock('fs');
const fs = require('fs');

describe('file reading test', () => {
    const filename = 'file';
    const fileData = '<p>Hello World</p>';

    beforeAll(() => {
        fs.__setMockFileData(filename, fileData);
    });

    ...

    test('reading an existing file should work', () => {
        const data = fileRead(filename);
        expect(data).toEqual(fileData);
    });
});
```
The `test('reading an existing file should work')` will be passed if `fileData` is equal to "<p>Hello World</p>"

Reading a directory is so much similar to this logic. You can also find more info [here](https://jestjs.io/docs/en/manual-mocks#examples)

### axios_fetch.test.js
This will send a get request with axios. So before test this module, we need to create a mock request for testing. [nock](https://www.npmjs.com/package/nock) is a great package for this.

```
const { axiosFetch } = require('./axios_fetch');
const nock = require('nock');

describe('fetching test', () => {
...
    test('reading from an existing URL should work', async () => {
        const url = 'https://test.ca';

        nock(url).get('/').reply(200);
        const status = await axiosFetch(url);
        expect(status).toEqual(200);
    });
...
})
``` 
`nock(url).get(root).reply(status)` will make a mock request which seems valid request just for testing. Once you make a fake http URL, you can test your fetch function using with this.

However, if you use axios you need to first set your `@jest-environment` configuration to node (default is jsdom).

For more information visit this [issue](https://github.com/axios/axios/issues/2654)

Now, your are read to test. result below:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/dy18c710etm4477fff3j.PNG)