SpyOn TypeORM repository to change the return value for unit testing NestJS

后端 未结 1 515
广开言路
广开言路 2021-02-04 02:30

I would like to unittest corner cases for my TypeORM database calls. I have already mocked all my TypeORM repositories with valid data. But I would like to SpyOn the repository

1条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-04 03:06

    Okay, after finally getting around to testing and playing with ideas I've found that this is a valid strategy

    1. Assume we have set up a PhotoEntity with basic properties, nothing too special (id, name, description, etc.)
    import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
    
    @Entity()
    export class Photo {
      @PrimaryGeneratedColumn()
      id: number;
    
      @Column({ length: 500 })
      name: string;
    
      @Column('text')
      description: string;
    
      @Column()
      filename: string;
    
      @Column('int')
      views: number;
    
      @Column()
      isPublished: boolean;
    }
    
    1. Set up a PhotoService such as the following (super basic but it will illustrate the point):
    import { Injectable } from '@nestjs/common';
    import { InjectRepository } from '@nestjs/typeorm';
    import { Repository } from 'typeorm';
    import { Photo } from './photo.entity';
    
    @Injectable()
    export class PhotoService {
      constructor(
        @InjectRepository(Photo)
        private readonly photoRepository: Repository,
      ) {}
    
      async findAll(): Promise {
        return await this.photoRepository.find();
      }
    }
    
    1. We can useClass: Repository so that we don't have to do any of the heavy lifting of setting up a repository class to use for testing (Repository is imported from the TypeORM package. We can then get the repo from the module and save it to a value for easy mocking and set up our tests like so:
    import { Test, TestingModule } from '@nestjs/testing';
    import { PhotoService } from './photo.service';
    import { getRepositoryToken } from '@nestjs/typeorm';
    import { Photo } from './photo.entity';
    import { Repository } from 'typeorm';
    
    describe('PhotoService', () => {
      let service: PhotoService;
      // declaring the repo variable for easy access later
      let repo: Repository;
    
      beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
          providers: [
            PhotoService,
            {
              // how you provide the injection token in a test instance
              provide: getRepositoryToken(Photo),
              // as a class value, Repository needs no generics
              useClass: Repository,
            },
          ],
        }).compile();
    
        service = module.get(PhotoService);
        // Save the instance of the repository and set the correct generics
        repo = module.get>(getRepositoryToken(Photo));
      });
    
      it('should be defined', () => {
        expect(service).toBeDefined();
      });
    
      it('should return for findAll', async () => {
        // mock file for reuse
        const testPhoto: Photo =  {
          id: 'a47ecdc2-77d6-462f-9045-c440c5e4616f',
          name: 'hello',
          description: 'the description',
          isPublished: true,
          filename: 'testFile.png',
          views: 5,
        };
        // notice we are pulling the repo variable and using jest.spyOn with no issues
        jest.spyOn(repo, 'find').mockResolvedValueOnce([testPhoto]);
        expect(await service.findAll()).toEqual([testPhoto]);
      });
    });
    
    1. Run your tests against the specified file or against all tests
    ▶ npm run test -- photo.service
    
    > nestjs-playground@0.0.1 test ~/Documents/code/nestjs-playground
    > jest "photo.service"
    
     PASS  src/photo/photo.service.spec.ts
      PhotoService
        ✓ should be defined (17ms)
        ✓ should return for findAll (4ms)  < -- test passes with no problem
    
    Test Suites: 1 passed, 1 total
    Tests:       2 passed, 2 total
    Snapshots:   0 total
    Time:        3.372s, estimated 4s
    Ran all test suites matching /photo.service/i.
    

    0 讨论(0)
提交回复
热议问题