我有一个 Typescript 类,它使用 InversifyJS 和Inversify Inject Decorators将服务注入私有属性。从功能上讲,这很好,但我在弄清楚如何对其进行单元测试时遇到了问题。我在下面创建了我的问题的简化版本。
在 Jasmine 单元测试中,我怎样才能用 a 替换注入RealDataService
的FakeDataService
?如果该属性不是私有的,我可以创建组件并分配一个假服务,但我想知道这是否可以通过使用 IOC 容器来实现。
我最初在 InversifyJS 食谱页面中遵循了这个示例,但很快意识到他们创建的容器没有在任何被测试的类中使用。此外,我在InversifyJS文档中看到的大多数代码示例都没有介绍如何对其进行单元测试。
这是问题的简化版本:
我的组件.ts
import { lazyInject, Types } from "./ioc";
import { IDataService } from "./dataService";
export default class MyComponent {
@lazyInject(Types.IDataService)
private myDataService!: IDataService;
getSomething(): string {
return this.myDataService.get();
}
}
数据服务.ts
import { injectable } from "inversify";
export interface IDataService {
get(): string;
}
@injectable()
export class RealDataService implements IDataService {
get(): string {
return "I am real!";
}
}
国际奥委会配置
import "reflect-metadata";
import { Container, ContainerModule, interfaces, BindingScopeEnum } from "inversify";
import getDecorators from "inversify-inject-decorators";
import { IDataService, RealDataService } from "./dataService";
const Types = {
IDataService: Symbol.for("IDataService")
};
const iocContainerModule = new ContainerModule((bind: interfaces.Bind) => {
bind<IDataService>(Types.IDataService).to(RealDataService);
});
const iocContainer = new Container();
iocContainer.load(iocContainerModule);
const { lazyInject } = getDecorators(iocContainer);
export { lazyInject, Types };
单元测试
import { Container } from "inversify";
import { Types } from "./ioc";
import MyComponent from "./myComponent";
import { IDataService } from "./dataService";
class FakeDataService implements IDataService {
get(): string {
return "I am fake!";
}
}
describe("My Component", () => {
let iocContainer!: Container;
let myComponent!: MyComponent;
beforeEach(() => {
iocContainer = new Container();
iocContainer.bind(Types.IDataService).to(FakeDataService);
// How do I make myComponent use this iocContainer?
// Is it even possible?
myComponent = new MyComponent();
});
it("should use the mocked service", () => {
const val = myComponent.getSomething();
expect(val).toBe("I am fake!");
});
});