jmcdo29 / testing-nestjs

A repository to show off to the community methods of testing NestJS including Unit Tests, Integration Tests, E2E Tests, pipes, filters, interceptors, GraphQL, Mongo, TypeORM, and more!
MIT License
2.92k stars 379 forks source link

README refers to non-existing cat.integration.spec.ts #1682

Open 4ndh4k opened 2 years ago

4ndh4k commented 2 years ago

As I was looking for some integration test inspiration I found this promising repo and even a reference to cat.integration.spec.ts in the README. Unfortunately it seems the actual file has been removed in fa73e575a1451ae0419cfc027404a685372e9d6d. 😢

Unless that was a mistake I suppose it should be fixed in the README. Out of curiosity, why was it removed?

jmcdo29 commented 2 years ago

Ah this was an issue of rehabbing the test from integration to e2e as that was the more appropriate term

jmcdo29 commented 2 years ago

Ah, actually, no I see what happened. I removed it because it was being ran with the unit tests and it required the running of a database server. It should have been moved to its own directory with its own test command and jest config, like the e2e tests, I just didn't set that up at the time.

For reference, here was the file ```ts /** * * Nest Modules */ import { Test, TestingModule } from '@nestjs/testing'; import { TypeOrmModule, getRepositoryToken } from '@nestjs/typeorm'; import { getConnection, Repository, DatabaseType } from 'typeorm'; /** * * Services */ import { CatService } from './cat.service'; /** * * Entities */ import { Cat } from './cat.entity'; /** * * Modules */ import { CatModule } from './cat.module'; import { CatDTO } from './cat.dto'; /** * Casting type as DatabaseType */ const postgresDatabase: DatabaseType = 'postgres'; /** * Database Credentials */ const credentials = { type: postgresDatabase, host: process.env.POSTGRES_HOST, port: Number(process.env.POSTGRES_PORT), username: process.env.POSTGRES_USER, password: process.env.POSTGRES_PASSWORD, database: process.env.POSTGRES_DB, entities: [__dirname + '/**/*.entity.{ts,js}'], dropSchema: false, synchronize: process.env.NODE_ENV.trim() !== 'production', logging: false, }; /** * Test cat object */ const cat: Partial = { name: 'Test Cat Mike', breed: 'Orange Tabby', age: 5, }; /** * Second test cat object */ const cat2: Partial = { name: 'Test Cat Mona', breed: 'Grey Shorthair', age: 7, }; describe('Cat Integration Tests', () => { let service: CatService; let repo: Repository; beforeAll(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [ CatModule, TypeOrmModule.forFeature([Cat]), TypeOrmModule.forRoot(credentials), ], providers: [CatService], }).compile(); service = module.get(CatService); repo = module.get>(getRepositoryToken(Cat)); }); describe('Add', () => { it('should be able to create a cat', async () => { // create new cat const newCat = await service.insertOne(cat); expect(newCat).toMatchObject({ name: cat.name }); expect(newCat).toMatchObject({ breed: cat.breed }); expect(newCat).toMatchObject({ age: cat.age }); expect(newCat).toBeTruthy(); }); }); describe('Edit', () => { const testNewName = 'Some Other Cat'; const testNewBreed = 'Grey Tabby'; const testNewAge = 7; let catDataToUpdate = { name: testNewName, breed: testNewBreed, age: testNewAge, }; it('should be able to update a cat', async () => { // create new cat const newCat = await service.insertOne(cat); // get new cat's id const { id } = newCat; // assign the newly created cat's id into the update object catDataToUpdate = { ...catDataToUpdate, ...{ id } }; // update cat const updatedCat = await service.updateOne(catDataToUpdate); expect(updatedCat).not.toMatchObject({ name: cat.name }); expect(updatedCat).not.toMatchObject({ breed: cat.breed }); expect(updatedCat).not.toMatchObject({ age: cat.age }); expect(updatedCat).toBeTruthy(); }); }); describe('Delete', () => { it('should be able to update a cat', async () => { // create new cat const newCat = await service.insertOne(cat); // delete cat const deletedCat = await service.deleteOne(newCat.id); expect(deletedCat).toMatchObject({ deleted: true }); }); }); describe('Get', () => { it('should be able to find all cats', async () => { // create new cat await service.insertOne(cat); // create new cat await service.insertOne(cat2); const cats = await service.getAll(); expect(cats.length).toEqual(2); }); }); describe('Get One', () => { it('should be able to find a cat by id', async () => { // create new cat const newCat = await service.insertOne(cat); const foundCat = await service.getOne(newCat.id); expect(foundCat.id).toEqual(newCat.id); }); it('should be able to find a cat by name', async () => { // create new cat const newCat = await service.insertOne(cat); const foundCat = await service.getOneByName(newCat.name); expect(foundCat.name).toEqual(newCat.name); }); }); /** * after each test, delete everything from cat table */ afterEach(async () => { await repo.query(`DELETE FROM cat`); }); /** * after all tests are done, delete everything from cat table */ afterAll(async () => { const connection = getConnection(); await connection.createQueryBuilder().delete().from(Cat).execute(); await connection.close(); }); }); ```
4ndh4k commented 2 years ago

Ah, ok thanks! Yeah, that makes sense.

Regarding naming things, in our project we try to distinguish between integration tests and e2e test in such a way that the integration is testing e.g a service in its smallest possible environment, just like the cat.integration.spec.ts, where as e2e attempt to test the whole app from its public APIs and from the perspective of a user journey..

But I see it's common to call both e2e tests