import { createMock } from '@golevelup/ts-jest' ; import { Test , TestingModule } from '@nestjs/testing' ; import { CatController } from './cat.controller' ; import { CatDTO } from './cat.dto' ; import { CatService } from './cat.service' ; import { Cat } from './interfaces/cat.interface' ; const testCat1 = 'Test Cat 1' ; const testBreed1 = 'Test Breed 1' ; describe ( 'Cat Controller' , ( ) => { let controller ; let service ; beforeEach ( async ( ) => { const module = await Test . createTestingModule ( { controllers : [ CatController ] , providers : [ { provide : CatService , useValue : { getAll : jest . fn ( ) . mockResolvedValue ( [ { name : testCat1 , breed : testBreed1 , age : 4 } , { name : 'Test Cat 2' , breed : 'Test Breed 2' , age : 3 } , { name : 'Test Cat 3' , breed : 'Test Breed 3' , age : 2 } , ] ) , getOne : jest . fn ( ) . mockImplementation ( ( id ) => Promise . resolve ( { name : testCat1 , breed : testBreed1 , age : 4 , _id : id , } ) ) , getOneByName : jest . fn ( ) . mockImplementation ( ( name ) => Promise . resolve ( { name , breed : testBreed1 , age : 4 } ) ) , insertOne : jest . fn ( ) . mockImplementation ( ( cat ) => Promise . resolve ( { _id : 'a uuid' , ... cat } ) ) , updateOne : jest . fn ( ) . mockImplementation ( ( cat ) => Promise . resolve ( { _id : 'a uuid' , ... cat } ) ) , deleteOne : jest . fn ( ) . mockResolvedValue ( { deleted : true } ) , } , } , ] , } ) . compile ( ) ; controller = module . get < CatController > ( CatController ) ; service = module . get < CatService > ( CatService ) ; } ) ; it ( 'should be defined' , ( ) => { expect ( controller ) . toBeDefined ( ) ; } ) ; describe ( 'getCats' , ( ) => { it ( 'should get an array of cats' , ( ) => { expect ( controller . getCats ( ) ) . resolves . toEqual ( [ { name : testCat1 , breed : testBreed1 , age : 4 , } , { name : 'Test Cat 2' , breed : 'Test Breed 2' , age : 3 , } , { name : 'Test Cat 3' , breed : 'Test Breed 3' , age : 2 , } , ] ) ; } ) ; } ) ; describe ( 'getById' , ( ) => { it ( 'should get a single cat' , ( ) => { expect ( controller . getById ( 'a strange id' ) ) . resolves . toEqual ( { name : testCat1 , breed : testBreed1 , age : 4 , _id : 'a strange id' , } ) ; expect ( controller . getById ( 'a different id' ) ) . resolves . toEqual ( { name : testCat1 , breed : testBreed1 , age : 4 , _id : 'a different id' , } ) ; } ) ; } ) ; describe ( 'getByName' , ( ) => { it ( 'should get a cat back' , async ( ) => { await expect ( controller . getByName ( 'Ventus' ) ) . resolves . toEqual ( { name : 'Ventus' , breed : testBreed1 , age : 4 , } ) ; const aquaMock = createMock < Cat > ( { name : 'Aqua' , breed : 'Maine Coon' , age : 5 , } ) ; const getByNameSpy = jest . spyOn ( service , 'getOneByName' ) . mockResolvedValueOnce ( aquaMock ) ; const getResponse = await controller . getByName ( 'Aqua' ) ; expect ( getResponse ) . toEqual ( aquaMock ) ; expect ( getByNameSpy ) . toBeCalledWith ( 'Aqua' ) ; } ) ; } ) ; describe ( 'newCat' , ( ) => { it ( 'should create a new cat' , ( ) => { const newCatDTO = { name : 'New Cat 1' , breed : 'New Breed 1' , age : 4 , } ; expect ( controller . newCat ( newCatDTO ) ) . resolves . toEqual ( { _id : 'a uuid' , ... newCatDTO , } ) ; } ) ; } ) ; describe ( 'updateCat' , ( ) => { it ( 'should update a new cat' , ( ) => { const newCatDTO = { name : 'New Cat 1' , breed : 'New Breed 1' , age : 4 , } ; expect ( controller . updateCat ( newCatDTO ) ) . resolves . toEqual ( { _id : 'a uuid' , ... newCatDTO , } ) ; } ) ; } ) ; describe ( 'deleteCat' , ( ) => { it ( 'should return that it deleted a cat' , ( ) => { expect ( controller . deleteCat ( 'a uuid that exists' ) ) . resolves . toEqual ( { deleted : true , } ) ; } ) ; it ( 'should return that it did not delete a cat' , ( ) => { const deleteSpy = jest . spyOn ( service , 'deleteOne' ) . mockResolvedValueOnce ( { deleted : false } ) ; expect ( controller . deleteCat ( 'a uuid that does not exist' ) ) . resolves . toEqual ( { deleted : false } ) ; expect ( deleteSpy ) . toBeCalledWith ( 'a uuid that does not exist' ) ; } ) ; } ) ; } ) ;