typescript - Hur man mockar typeORM-repository


Jag skulle vilja skriva några tester och mocka typeORM-repositoriet. Har provat några saker men kunde inte lösa det... (som .. @InjectRepository)... Några tankar?

import { AfterRoutesInit, Service } from '@tsed/common';
import { TypeORMService } from '@tsed/typeorm';
import { Connection, Repository } from 'typeorm';
import { DbAccount } from '../entity/DbAccount';
import { DbAddress } from '../entity/DbAddress';
import { Account } from '../models/Account';
import { Address } from '../models/address';
import { Pageable } from '../models/api_common/Pageable';

@Service()
export default class AccountService implements AfterRoutesInit {
    private repository: Repository<DbAccount>;
    private addressRepository: Repository<DbAddress>;

    constructor(private typeORMService: TypeORMService) { }

    $afterRoutesInit(): void | Promise<any> {
        const connection: Connection = this.typeORMService.get('default');
        this.repository = connection.getRepository(DbAccount);
        this.addressRepository = connection.getRepository(DbAddress);
    }

    async delete(accountId: string): Promise<void> {
        await this.repository.delete(accountId);

        return;
    }

}

Svar #1

Jag vet inte om ditt problem är löst men här är en lösning:

import {TestContext} from "@tsed/testing";
import {TypeORMService} from "@tsed/typeorm";
import {expect} from "chai";
import * as Sinon from "sinon";
import {AccountService} from "./AccountService";
import {DbAccount} from "./DbAccount";
import {DbAddress} from "./DbAddress";

describe("AccountService", () => {
  before(() => TestContext.create());
  after(() => TestContext.reset());
  describe("afterRoutesInit()", () => {
    it("should initialise repository when afterRoutesInit event is emitted", () => {
      // GIVEN
      const connection = {
        getRepository: Sinon.stub()
      };
      const typeORMService = {
        get: Sinon.stub().returns(connection)
      };
      const dbAccountRepository = {name: "dbAccountRepository"};
      const dbAddressRepository = {name: "dbAddressRepository"};

      connection.getRepository
        .withArgs(DbAccount).returns(dbAccountRepository);
      connection.getRepository
        .withArgs(DbAddress).returns(dbAddressRepository);

      const service = TestContext.invoke<AccountService>(AccountService, [
        {
          provide: TypeORMService,
          use: typeORMService
        }
      ]);

      // WHEN
      service.$afterRoutesInit();

      // THEN
      expect(typeORMService.get).to.have.been.calledWithExactly("default");
      expect(service.repository).to.deep.eq(dbAccountRepository);
      expect(service.addressRepository).to.deep.eq(dbAddressRepository);
    });
  });
});

Observera: Jag använder chai och sinon för att skriva enhetstester :)

Svar #2

Så här gör jag det.

import sinon from 'sinon';
import {ConnectionManager, Repository, Connection} from 'typeorm';

describe('Auth service Unit tests:', () => {
   const sandbox = sinon.createSandbox()
   beforeEach(() => {
    sandbox.stub(ConnectionManager.prototype, 'get').returns({
      getRepository: sandbox.stub().returns(sinon.createStubInstance(Repository))
    } as unknown as Connection)
   })

   afterEach(() => {
     sandbox.restore();
   })

   it('login() with valid username and password', (done) => {
      // Test here 
   }) 
})