How To Integrate and Write Ava Unit Test In Rio Project
Published: 2022-11-17 19:46:20

Git -> https://github.com/retterio/Ava-UnitTest/tree/main

AVA is a test runner for Node.js. In this article we will learn how to integrate it to our Rio Project. As project we will use Rio template project created with `"rio init"`. So let's dive into it.

## Dependencies
First we should add required dependencies to our project. Add dependencies below to `package.json` in project directory.
After that save and install the dependencies.
```json
{
    "@types/node": "14.17.2",
    "ts-node": "10.4.0",
    "tsconfig-paths": "^3.13.0",
    "dotenv": "16.0.0",
    "ava": "4.0.1",
}
```

## Configuration

After adding dependencies, Ava needs a config file that lets us tell Ava where the test files are located. So let's create this config file.  

```
ava.config.cjs
```
 in project directory and add code below to that file.
```typescript
module.exports = {
  timeout: '180s',
  files: ['**/__tests__/**/*.ava.ts', '**/__tests__/**/*.ava.ts', '**/__tests__/**/*.test.ts'],
  extensions: ['ts', 'js'],
  require: ['ts-node/register', 'tsconfig-paths/register', 'dotenv/config'],
  environmentVariables: {},
}
```

Now create a folder called `"__tests__"` inside desired class, for us this is the `"Test"` class. This folder will keep our test files. Inside this folder you can create your test files.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ecjwhpkkmp64wexcmnz.png)


# Writing Tests

Now we can begin testing! So create a file named `"index.test.ava.ts"`, naming is important here. In config we told Ava where to search for tests and what to expect in file names. Now add code below to this file. 
```typescript
import { Data } from "@retter/rdk"
import test from 'ava'
import { cloneDeep } from 'lodash'

const getMockedRioData = (): Data => ({
    state: {
        public: {},
        private: {},
    }, 
    request: {},
    response: {},
} as any)


```
`"getMockedData"` is the data we will send to our functions. You can see we have `state`, `request` and `response` here. So let's create our target function and its unit test !

# Test Your Response

Lets write a test that simply checking status code of our response

**Function**
```typescript
export async function responseTest(data: Data): Promise<Data> {
    data.response = {
        statusCode: 200,
        body: { message: "Hello World!" },
    };
    return data;
}
```

** Scenario 1 **
```typescript
test.serial('test that suppose to succeed', async (t) => {
    const data = getMockedRioData()
    await responseTest(data)
    t.is(data.response.statusCode, 200)
    t.is(data.response.body.message, "Hello World!")
})
```
Result

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xa3pwkd4qdvb0vyh1spu.png)

** Scenario 2 **
```typescript
test.serial('Test that suppose to fail', async (t) => {
    const data = getMockedRioData()
    await responseTest(data)
    t.not(data.response.statusCode, 200)
})
```
Result

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2eoc3tukwc4887oh31d6.png)

# Test Your Request

**Function**
```typescript
export async function requestTest(data: Data): Promise<Data> {
    const { name }  = data.request.body
    data.state.public.name = name
    data.response = {
        statusCode: 200,
    };
    return data;
}
```

**Test**
```typescript
test.serial('Request Test', async (t) => {
    const data = getMockedRioData()
    data.request.body = {
        name: "Bahadir"
    }
    await requestTest(data)
    t.is(data.state.public.name, "Bahadir")
})
```

We sent `name` in our body, our function suppose to change our state with this input so in test we are checking if states `name` got equal with requests `name`

Finally to run test you can install Visual Studio Code extension called `ava-launch` or you can type `npx Ava` in terminal.

And that's it now you can create tests for your Rio projects. I hope you understand it :)

Thanks for reading this article. See you on the next one :)

# References 
Rio Docs -> https://docs.retter.io
Ava -> https://github.com/avajs/ava