首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何模拟typeorm连接

如何模拟typeorm连接
EN

Stack Overflow用户
提问于 2020-03-23 12:40:13
回答 1查看 7.1K关注 0票数 6

在集成测试中,我使用以下代码段创建连接

代码语言:javascript
复制
import {Connection, createConnection} from 'typeorm';
// @ts-ignore
import options from './../../../ormconfig.js';

export function connectDb() {
  let con: Connection;

  beforeAll(async () => {
    con = await createConnection(options);
  });

  afterAll(async () => {
    await con.close();
  });

}

我正在尝试对一个类进行单元测试,该类在其方法中调用typeorm存储库,如果没有调用上面的助手函数connectDb(),我将得到下面的错误,这当然是应该的。

ConnectionNotFoundError:没有找到连接“默认”。

我的问题是如何模拟连接。我试过以下几种方法,但都没有成功

代码语言:javascript
复制
import typeorm, {createConnection} from 'typeorm';
// @ts-ignore
import options from "./../../../ormconfig.js";

const mockedTypeorm = typeorm as jest.Mocked<typeof typeorm>;

jest.mock('typeorm');

 beforeEach(() => {
    //mockedTypeorm.createConnection.mockImplementation(() => createConnection(options)); //Failed
    mockedTypeorm.createConnection = jest.fn().mockImplementation(() => typeorm.Connection);

    MethodRepository.prototype.changeMethod = jest.fn().mockImplementation(() => {
      return true;
    });
  });

使用这种模拟运行测试会出现此错误。

TypeError:装饰师不是一个函数

注意事项:如果我在测试中调用connectDb(),一切正常。但是我不想这样做,因为在运行任何测试之前,需要花费太多的时间将一些数据插入到db中。为了简单起见,省略了一些代码。如有任何帮助,将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2021-01-05 10:31:56

经过大量的研究和实验,我终于得到了这个解决方案。我希望这对经历过同样问题的人有用..。

它不需要任何DB connection

  • testing服务层的内容,而不是DB层本身的

  • 测试可以涵盖所有我需要不费吹灰之力地进行测试的情况,我只需要为相关的类型方法提供正确的输出。

这是我想测试的方法

代码语言:javascript
复制
@Injectable()
export class TemplatesService {
  constructor(private readonly templatesRepository: TemplatesRepository) {}

  async list(filter: ListTemplatesReqDTO) {
    const qb = this.templatesRepository.createQueryBuilder("tl");
    const { searchQuery, ...otherFilters } = filter;
    if (filter.languages) {
      qb.where("tl.language IN (:...languages)");
    }
    if (filter.templateTypes) {
      qb.where("tl.templateType IN (:...templateTypes)");
    }
    if (searchQuery) {
      qb.where("tl.name LIKE :searchQuery", { searchQuery: `%${searchQuery}%` });
    }
    if (filter.skip) {
      qb.skip(filter.skip);
    }
    if (filter.take) {
      qb.take(filter.take);
    }
    if (filter.sort) {
      qb.orderBy(filter.sort, filter.order === "ASC" ? "ASC" : "DESC");
    }
    return qb.setParameters(otherFilters).getManyAndCount();
  }

...
}

这是一个考验:

代码语言:javascript
复制
import { SinonStub, createSandbox, restore, stub } from "sinon";
import * as typeorm from "typeorm";

describe("TemplatesService", () => {
  let service: TemplatesService;
  let repo: TemplatesRepository;

  const sandbox = createSandbox();
  const connectionStub = sandbox.createStubInstance(typeorm.Connection);
  const templatesRepoStub = sandbox.createStubInstance(TemplatesRepository);
  const queryBuilderStub = sandbox.createStubInstance(typeorm.SelectQueryBuilder);
  stub(typeorm, "createConnection").resolves((connectionStub as unknown) as typeorm.Connection);
  connectionStub.getCustomRepository
    .withArgs(TemplatesRepository)
    .returns((templatesRepoStub as unknown) as TemplatesRepository);

  beforeAll(async () => {
    const builder: TestingModuleBuilder = Test.createTestingModule({
      imports: [
        TypeOrmModule.forRoot({
          type: "postgres",
          database: "test",
          entities: [Template],
          synchronize: true,
          dropSchema: true
        })
      ],
      providers: [ApiGuard, TemplatesService, TemplatesRepository],
      controllers: []
    });
    const module = await builder.compile();

    service = module.get<TemplatesService>(TemplatesService);
    repo = module.get<TemplatesRepository>(TemplatesRepository);
  });

  beforeEach(async () => {
    // do something
  });

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

  it("Service should be defined", () => {
    expect(service).toBeDefined();
  });


  describe("list", () => {
    let fakeCreateQueryBuilder;

    it("should return records", async () => {
      stub(queryBuilderStub, "skip" as any).returnsThis();
      stub(queryBuilderStub, "take" as any).returnsThis();
      stub(queryBuilderStub, "sort" as any).returnsThis();
      stub(queryBuilderStub, "setParameters" as any).returnsThis();
      stub(queryBuilderStub, "getManyAndCount" as any).resolves([
        templatesRepoMocksListSuccess,
        templatesRepoMocksListSuccess.length
      ]);
      fakeCreateQueryBuilder = stub(repo, "createQueryBuilder" as any).returns(queryBuilderStub);
      const [items, totalCount] = await service.list({});

      expect(fakeCreateQueryBuilder.calledOnce).toBe(true);
      expect(fakeCreateQueryBuilder.calledOnce).toBe(true);
      expect(items.length).toBeGreaterThan(0);
      expect(totalCount).toBeGreaterThan(0);
    });
  });
});

干杯!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60813752

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档