# 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kinesis-school-of-programming.gitbook.io/nestjs-unleashed/extra-module-6-automated-testing/unit-tests/mocks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
