Мне не удалось успешно найти, как заглушить вложенный репозиторий typeorm. Может ли кто-нибудь помочь мне создать заглушку sinon для следующего кода. У меня есть код в тестовом файле, который я нашел в другом вопросе о стеке, но он не работает. Конкретная строка кода, которую я хочу заглушить:
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);
});
});
Заранее спасибо!
Обновлено: я добавил больше в тестовый файл, чтобы было более понятно, что я пытаюсь сделать.
Я только что обновил свой пост, чтобы показать импорт в project.controller.ts.
Вы можете использовать Link Seams с CommonJS , поэтому мы будем использовать 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 |
-----------------------|---------|----------|---------|---------|-------------------
Большое спасибо, это сработало! Как вы думаете, можно ли это реализовать в шутку? Просто интересуюсь
@lmircetic Вы должны задать новый вопрос.
Как вы импортировали
getManager
?