如何在 TypeORM 中存根嵌套存储库?
How to stub nested Repository in TypeORM?
我没能成功找到如何存根 typeorm 嵌套存储库。有人可以帮我为以下代码构建一个 sinon 存根吗?我在另一个 Whosebug 问题中找到的测试文件中有一些代码,但它不起作用。
我希望存根的具体代码行是:
const project = await getManager().getRepository(Project).find({ where: queryParams });
这是源代码:
project.controller.ts
//getConnection and UpdateResult not used in this function btw
import {
EntityManager,
getConnection,
getManager,
UpdateResult,
} from "typeorm";
import { Project } from "./project.entity";
import { validate } from "class-validator";
import logger from "../../utils/logger";
export const findOneProject = async (queryParams: {}): Promise<
Project
> => {
try {
const project = await getManager().getRepository(Project).find({
where: queryParams,
});
if (project.length > 1) {
throw new Error("Found more than one project");
}
return project[0];
} catch (e) {
throw new Error(`Unable to find project: ${e.message}`);
}
};
project.test.ts
import sinon from "sinon";
import { findOneProject } from "./project.controller";
import { Project } from "./project.entity";
import { EntityManager, Repository } from "typeorm";
const mockProject = {
ID: "insert-id-here",
name: "name",
};
describe("Testing findOneProject", () => {
it("Should return the same project", () => {
const sandbox = sinon.createSandbox();
// I think that i can get the repository to be stubbed but idk how to stub the find()
sandbox.stub(EntityManager.prototype, "get").returns({
getRepository: sandbox
.stub()
.returns(sinon.createStubInstance(Repository)),
});
const project = await findOneProject(ID: "insert-id-here");
expect(project).toBe(mockProject);
});
});
提前致谢!
编辑:我在测试文件中添加了更多内容以使其更清楚我正在尝试做什么
您可以使用 Link Seams with CommonJS, so we will be using proxyquire 构建我们的接缝。
例如
project.controller.ts
:
import { getManager } from 'typeorm';
import { Project } from './project.entity';
export const findOneProject = async (queryParams: {}): Promise<Project> => {
try {
const project = await getManager()
.getRepository(Project)
.find({
where: queryParams,
});
if (project.length > 1) {
throw new Error('Found more than one project');
}
return project[0];
} catch (e) {
throw new Error(`Unable to find project: ${e.message}`);
}
};
project.entity.ts
:
export class Project {
// whatever
}
project.controller.test.ts
:
import sinon from 'sinon';
import chai, { expect } from 'chai';
import proxyquire from 'proxyquire';
import { Project } from './project.entity';
import chaiAsPromised from 'chai-as-promised';
chai.use(chaiAsPromised);
const mockProject = {
ID: 'insert-id-here',
name: 'name',
};
describe('Testing findOneProject', () => {
let sandbox: sinon.SinonSandbox;
before(() => {
sandbox = sinon.createSandbox();
});
it('Should return the same project', async () => {
const typeormStub = {
getManager: sandbox.stub().returnsThis(),
getRepository: sandbox.stub().returnsThis(),
find: sandbox.stub().resolves([mockProject]),
};
const { findOneProject } = proxyquire('./project.controller', {
typeorm: typeormStub,
});
const project = await findOneProject({ id: 1 });
sandbox.assert.calledOnce(typeormStub.getManager);
sandbox.assert.calledWithExactly(typeormStub.getRepository, Project);
sandbox.assert.calledWithExactly(typeormStub.find, { where: { id: 1 } });
expect(project).to.be.eq(mockProject);
});
it('should throw error if found more than one project', async () => {
const typeormStub = {
getManager: sandbox.stub().returnsThis(),
getRepository: sandbox.stub().returnsThis(),
find: sandbox.stub().resolves([{ name: 'a' }, { name: 'b' }]),
};
const { findOneProject } = proxyquire('./project.controller', {
typeorm: typeormStub,
});
await expect(findOneProject({ id: 1 })).to.be.rejectedWith('Found more than one project');
sandbox.assert.calledOnce(typeormStub.getManager);
sandbox.assert.calledWithExactly(typeormStub.getRepository, Project);
sandbox.assert.calledWithExactly(typeormStub.find, { where: { id: 1 } });
});
it('should throw error if find project error', async () => {
const typeormStub = {
getManager: sandbox.stub().returnsThis(),
getRepository: sandbox.stub().returnsThis(),
find: sandbox.stub().rejects(new Error('timeout')),
};
const { findOneProject } = proxyquire('./project.controller', {
typeorm: typeormStub,
});
await expect(findOneProject({ id: 1 })).to.be.rejectedWith('Unable to find project: timeout');
sandbox.assert.calledOnce(typeormStub.getManager);
sandbox.assert.calledWithExactly(typeormStub.getRepository, Project);
sandbox.assert.calledWithExactly(typeormStub.find, { where: { id: 1 } });
});
});
单元测试结果:
Testing findOneProject
✓ Should return the same project (2395ms)
✓ should throw error if found more than one project
✓ should throw error if find project error
3 passing (2s)
-----------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
project.controller.ts | 100 | 100 | 100 | 100 |
project.entity.ts | 100 | 100 | 100 | 100 |
-----------------------|---------|----------|---------|---------|-------------------
我没能成功找到如何存根 typeorm 嵌套存储库。有人可以帮我为以下代码构建一个 sinon 存根吗?我在另一个 Whosebug 问题中找到的测试文件中有一些代码,但它不起作用。 我希望存根的具体代码行是:
const project = await getManager().getRepository(Project).find({ where: queryParams });
这是源代码:
project.controller.ts
//getConnection and UpdateResult not used in this function btw
import {
EntityManager,
getConnection,
getManager,
UpdateResult,
} from "typeorm";
import { Project } from "./project.entity";
import { validate } from "class-validator";
import logger from "../../utils/logger";
export const findOneProject = async (queryParams: {}): Promise<
Project
> => {
try {
const project = await getManager().getRepository(Project).find({
where: queryParams,
});
if (project.length > 1) {
throw new Error("Found more than one project");
}
return project[0];
} catch (e) {
throw new Error(`Unable to find project: ${e.message}`);
}
};
project.test.ts
import sinon from "sinon";
import { findOneProject } from "./project.controller";
import { Project } from "./project.entity";
import { EntityManager, Repository } from "typeorm";
const mockProject = {
ID: "insert-id-here",
name: "name",
};
describe("Testing findOneProject", () => {
it("Should return the same project", () => {
const sandbox = sinon.createSandbox();
// I think that i can get the repository to be stubbed but idk how to stub the find()
sandbox.stub(EntityManager.prototype, "get").returns({
getRepository: sandbox
.stub()
.returns(sinon.createStubInstance(Repository)),
});
const project = await findOneProject(ID: "insert-id-here");
expect(project).toBe(mockProject);
});
});
提前致谢!
编辑:我在测试文件中添加了更多内容以使其更清楚我正在尝试做什么
您可以使用 Link Seams with CommonJS, so we will be using proxyquire 构建我们的接缝。
例如
project.controller.ts
:
import { getManager } from 'typeorm';
import { Project } from './project.entity';
export const findOneProject = async (queryParams: {}): Promise<Project> => {
try {
const project = await getManager()
.getRepository(Project)
.find({
where: queryParams,
});
if (project.length > 1) {
throw new Error('Found more than one project');
}
return project[0];
} catch (e) {
throw new Error(`Unable to find project: ${e.message}`);
}
};
project.entity.ts
:
export class Project {
// whatever
}
project.controller.test.ts
:
import sinon from 'sinon';
import chai, { expect } from 'chai';
import proxyquire from 'proxyquire';
import { Project } from './project.entity';
import chaiAsPromised from 'chai-as-promised';
chai.use(chaiAsPromised);
const mockProject = {
ID: 'insert-id-here',
name: 'name',
};
describe('Testing findOneProject', () => {
let sandbox: sinon.SinonSandbox;
before(() => {
sandbox = sinon.createSandbox();
});
it('Should return the same project', async () => {
const typeormStub = {
getManager: sandbox.stub().returnsThis(),
getRepository: sandbox.stub().returnsThis(),
find: sandbox.stub().resolves([mockProject]),
};
const { findOneProject } = proxyquire('./project.controller', {
typeorm: typeormStub,
});
const project = await findOneProject({ id: 1 });
sandbox.assert.calledOnce(typeormStub.getManager);
sandbox.assert.calledWithExactly(typeormStub.getRepository, Project);
sandbox.assert.calledWithExactly(typeormStub.find, { where: { id: 1 } });
expect(project).to.be.eq(mockProject);
});
it('should throw error if found more than one project', async () => {
const typeormStub = {
getManager: sandbox.stub().returnsThis(),
getRepository: sandbox.stub().returnsThis(),
find: sandbox.stub().resolves([{ name: 'a' }, { name: 'b' }]),
};
const { findOneProject } = proxyquire('./project.controller', {
typeorm: typeormStub,
});
await expect(findOneProject({ id: 1 })).to.be.rejectedWith('Found more than one project');
sandbox.assert.calledOnce(typeormStub.getManager);
sandbox.assert.calledWithExactly(typeormStub.getRepository, Project);
sandbox.assert.calledWithExactly(typeormStub.find, { where: { id: 1 } });
});
it('should throw error if find project error', async () => {
const typeormStub = {
getManager: sandbox.stub().returnsThis(),
getRepository: sandbox.stub().returnsThis(),
find: sandbox.stub().rejects(new Error('timeout')),
};
const { findOneProject } = proxyquire('./project.controller', {
typeorm: typeormStub,
});
await expect(findOneProject({ id: 1 })).to.be.rejectedWith('Unable to find project: timeout');
sandbox.assert.calledOnce(typeormStub.getManager);
sandbox.assert.calledWithExactly(typeormStub.getRepository, Project);
sandbox.assert.calledWithExactly(typeormStub.find, { where: { id: 1 } });
});
});
单元测试结果:
Testing findOneProject
✓ Should return the same project (2395ms)
✓ should throw error if found more than one project
✓ should throw error if find project error
3 passing (2s)
-----------------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
project.controller.ts | 100 | 100 | 100 | 100 |
project.entity.ts | 100 | 100 | 100 | 100 |
-----------------------|---------|----------|---------|---------|-------------------