# Mocks

Inside the <mark style="color:purple;">src</mark> folder, create the file <mark style="color:purple;">testing</mark>/<mark style="color:purple;">util</mark>/<mark style="color:purple;">testing.util</mark>. Here, we can create a type to represent a <mark style="color:blue;">`MockRepository`</mark>, and a function to instantiate a base mock. Let's then get to it.

Fortunately, with the library we installed earlier, this process will become much simpler. We can use the <mark style="color:blue;">`MockProxy`</mark> type and pass the <mark style="color:blue;">`Repository`</mark> with an **entity**, in order to generate the type for a <mark style="color:blue;">`MockRepository`</mark>. A generic that extends <mark style="color:blue;">`ObjectLiteral`</mark> (the same type required in the TypeORM <mark style="color:blue;">`Repository`</mark>) may prove adequate.

```typescript
export type MockRepository<TEntity extends ObjectLiteral> = MockProxy<Repository<TEntity>>;
```

We can then create a function that will generate a **generic mock**. As the variables that will receive this call will already be properly typed, this function won't need any additional typing.

```typescript
export const createMock = () => mock();
```

The result will be the following: we'll get a base mock that may be built upon to provide mocked behavior. Due to the type of the <mark style="color:blue;">`repository`</mark>, we may only mock its methods and not arbitrary fields, ensuring type safety. These mocked methods will have no logic by default, and for each scenario, a specific behavior can be applied.

Going back to the test file, we shall perform the following steps:

* Create a variable for the <mark style="color:blue;">`repository`</mark> below the <mark style="color:blue;">`service`</mark>

```typescript
let repository: MockRepository<User>;
```

* Call the function to create a base mock

```typescript
useValue: createMock(),
```

* Obtain its reference from the <mark style="color:blue;">`module`</mark>

```typescript
repository = module.get(getRepositoryToken(User));
```

Back in the test for the <mark style="color:blue;">`findOne()`</mark> method, if we then mock the method that would be called in the <mark style="color:blue;">`repository`</mark> (and do it before the <mark style="color:blue;">`service`</mark> call, of course, and assert it to <mark style="color:blue;">`User`</mark> for a moment), the test will <mark style="color:green;">pass</mark>!

```typescript
repository.findOneByOrFail.mockResolvedValueOnce(expectedUser as User);
```

{% hint style="info" %}
Some considerations:

* The method <mark style="color:blue;">`mockReturnValue()`</mark> makes the chained method **return** the value
* By using <mark style="color:blue;">`Resolved`</mark>, a <mark style="color:green;">resolved</mark> promise is returned
* And by using <mark style="color:blue;">`Once`</mark>, after this call the logic is **reset**
  {% endhint %}

Before proceeding to the other tests, let's just create three auxiliary functions at the bottom of the file. The **faker** library will be used to automatically generate fake data. But we need to import it manually.

```typescript
import { faker } from '@faker-js/faker';
```

They will be for creating:

* A fake <mark style="color:blue;">`createUserDto`</mark>

```typescript
const genCreateDto = (): CreateUserDto => ({
  name: faker.person.firstName(),
  email: faker.internet.email(),
  phone: faker.phone.number(),
  password: faker.internet.password(),
});
```

* A fake <mark style="color:blue;">`updateUserDto`</mark>

```typescript
const genUpdateDto = (): UpdateUserDto => ({
  name: faker.person.firstName(),
});
```

* A fake <mark style="color:blue;">`user`</mark>

```typescript
const genUser = (id: number, createDto = genCreateDto()) =>
  ({
    id,
    ...createDto,
  }) as User;
```

{% hint style="info" %}
Note the **parameter default** in case a <mark style="color:blue;">`createDto`</mark> is not passed.
{% endhint %}

With the help of these, we can more easily write our tests. Let's then just use the last one in the test to generate the <mark style="color:blue;">`expectedUser`</mark> (and remove the type assertion)...

```typescript
const expectedUser = genUser(id);
```

...and then proceed to the remaining tests.
