> For the complete documentation index, see [llms.txt](https://kinesis-school-of-programming.gitbook.io/nestjs-unleashed/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kinesis-school-of-programming.gitbook.io/nestjs-unleashed/extra-module-6-automated-testing/unit-tests/mocks.md).

# Mocks

External dependencies can be simulated by simple representations.

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.

First, install two packages for the following purposes:

* **Mocking** in an efficient way
* Creating **fake data** quickly.

```shellscript
yarn add -D vitest-mock-extended @faker-js/faker
```

With the first library, 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**, 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 create a user-related **factory**. It will help with instantiating elements such as the DTOs and the entity itself, with **fake data** from the **faker** library. Create it then in <mark style="color:purple;">testing</mark>/<mark style="color:purple;">factories</mark>/<mark style="color:purple;">user.factory</mark> as a class with **static** methods.

```typescript
export class UserFactory {}
```

Inside, we'll use the [fishery](https://www.npmjs.com/package/fishery) package for the actual factories. The benefit is that we may provide defaults while also accepting overrides, among other advantages.

```shellscript
yarn add -D fishery
```

They will be for creating:

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

```typescript
static createDto = Factory.define<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
static updateDto = Factory.define<UpdateUserDto>(() => ({
  name: faker.person.firstName(),
}));
```

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

```typescript
static user = Factory.define<User>(() => {
  const user = UserFactory.createDto.build() as User;
  return user;
});
```

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

```typescript
const expectedUser = UserFactory.user.build({ id });
```

...and then proceed to the remaining tests.
