# Simulated environment

Well, before proceeding to the users tests, let's have a test database in order to test the CRUD operations. An actual **Postgres database** will be used so that the tests are closer to a real-world scenario. **Environment variables** will also be used for better organization.

We should then create the file <mark style="color:purple;">.env.test.local</mark>, following the convention in the <mark style="color:purple;">.gitignore</mark> file. There, copy the database credentials and just set the <mark style="color:blue;">`DATABASE_PORT`</mark> to <mark style="color:blue;">5433</mark>, as to prevent a collision with the development database.

Once again in the <mark style="color:purple;">docker-compose.yml</mark> file, create a service for the test database:

```yaml
test-database:
  image: postgres
  restart: always
  ports:
    - ${DATABASE_PORT}:5432
  environment:
    POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
```

And in the file <mark style="color:purple;">package.json</mark>, let's add a <mark style="color:blue;">pre</mark> and <mark style="color:blue;">post</mark> scripts for <mark style="color:blue;">`test:e2e`</mark> around it. They will be responsible for, respectively, **creating** and **excluding** the test database (and volume). Please note that we should also pass <mark style="color:orange;">--env-file</mark> to indicate the <mark style="color:purple;">.env</mark> file to be used in <mark style="color:purple;">docker-compose.yml</mark>.

```json
"pretest:e2e": "docker-compose --env-file .env.test.local up -d test-database",
"posttest:e2e": "docker-compose --env-file .env.test.local stop test-database && docker-compose --env-file .env.test.local rm -fv test-database",
```

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

* We may also use the <mark style="color:orange;">s</mark> flag for <mark style="color:orange;">rm</mark> (resulting in <mark style="color:orange;">-sfv</mark>), which would stop the container before removing, and allow for deleting the previous command for stopping (bit slower than the way shown above)
* If the tests <mark style="color:red;">fail</mark>, the test database will need to be deleted manually with the <mark style="color:blue;">post</mark> script
  {% endhint %}

Inside the <mark style="color:purple;">src</mark> folder, we can then create a **configuration namespace** for the test database in <mark style="color:purple;">testing</mark> -> <mark style="color:purple;">config</mark> -> <mark style="color:purple;">test-database.config</mark>.

```typescript
export default registerAs('testDatabase', () => {
  const user = process.env.DATABASE_USER;
  const password = process.env.DATABASE_PASSWORD;
  const host = process.env.DATABASE_HOST;
  const port = process.env.DATABASE_PORT;
  const name = process.env.DATABASE_NAME;

  const url = `postgresql://${user}:${password}@${host}:${port}/${name}`;

  const config = {
    type: 'postgres',
    url,
    autoLoadEntities: true,
    synchronize: true,
  } as const satisfies TypeOrmModuleOptions;
  return config;
});
```

{% hint style="info" %}
Here, we turn on <mark style="color:blue;">`synchronize`</mark> to automatically execute the migrations.
{% endhint %}

And we can create the file <mark style="color:purple;">testing</mark>/<mark style="color:purple;">util</mark>/<mark style="color:purple;">testing.constants</mark> with the **validation schema** for the testing environment variables.

```typescript
export const TEST_ENV_VALIDATION_SCHEMA = Joi.object({
  DATABASE_USER: Joi.required(),
  DATABASE_PASSWORD: Joi.required(),
  DATABASE_HOST: Joi.required(),
  DATABASE_PORT: Joi.number().port().required(),
  DATABASE_NAME: Joi.required(),
});
```

We may then proceed to the actual 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/e2e-tests/simulated-environment.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.
