【发布时间】:2017-09-28 02:36:07
【问题描述】:
我试图在 Aurelia 测试中模拟几个服务,但一个是模拟注入,另一个是注入真正的服务。我看不出有什么区别。
我的测试规范中有几个服务模拟:
export class MockCommunicationService {
imAmock = true;
get(id: number): Promise<ICommunication> {
return Promise.resolve({} as ICommunication);
}
}
export class MockRoundService {
getRounds(): Promise<IRoundList[]> {
return Promise.resolve([{} as IRoundList]);
}
}
你可以看到我放在那里的imAmock测试属性,以便稍后检查。
我的测试(在 TypeScript 中)看起来像这样,主要取自 aurelia hub 关于测试的文档:
describe('Communications', () => {
let component: ComponentTester;
let container: Container;
let viewModel: Communications; // <-- the real type
let service = new MockCommunicationService();
let roundService = new MockRoundService();
beforeEach(() => {
container = new Container();
viewModel = container.get(Communications);
component = StageComponent
.withResources(PLATFORM.moduleName('path/to/real/communications'))
.inView('<communications></communications>')
.boundTo(viewModel);
component.bootstrap(aurelia => {
aurelia.use.standardConfiguration()
.plugin(PLATFORM.moduleName("aurelia-validation"));
aurelia.container.registerInstance(RoundService, roundService);
aurelia.container.registerInstance(CommunicationService, service);
});
});
it('should be mocked', done => {
component.create(bootstrap).then(() => {
expect(viewModel.communicationService.imAmock).toBe(true);
done();
}).catch(e => { console.log(e.toString()) });
});
});
由于 imAmock 未定义而失败。如果我console.log(viewModel.communicationService) 我可以看到真正的通信服务及其所有注入的依赖项(例如http等)
但是,如果我对RoundService 做同样的事情,上面的模拟就会像你期望的那样被注入。
viewModel 本身对两种服务使用 @autoinject 的方式相同:
@autoinject()
export class Communications {
...
constructor(public readonly communicationService: CommunicationService, public readonly roundService: RoundService,
private readonly bindingEngine: BindingEngine, private readonly eventAggregator: EventAggregator, private readonly animator: CssAnimator,
private readonly validationControllerFactory: ValidationControllerFactory) {
...
}
}
(我将前两个公开,以便我可以在测试中访问它们,但它们通常是私有的)
我能找到的唯一提示是 Aurelia DI 实现使用键映射(通常是类)来解析实例。如果我以某种方式定义了 CommunicationService 两次,那么我可能会为同一个类获得两个不同的键......但我看不出这是如何发生的或如何解决它。
非常感谢您的帮助!
编辑! 感谢@adam-willden below,我开始思考如何重新排序注册和第一个 container.get 调用,我想出了这个:
beforeEach(() => {
container = new Container();
component = StageComponent
.withResources(PLATFORM.moduleName('path/to/real/communications'))
.inView('<communications></communications>')
.boundTo(viewModel);
component.bootstrap(aurelia => {
aurelia.use.standardConfiguration()
.plugin(PLATFORM.moduleName("aurelia-validation"));
aurelia.container.registerInstance(RoundService, roundService);
aurelia.container.registerInstance(CommunicationService, service);
viewModel = aurelia.container.get(Communications);
});
});
这是一种享受,现在这两个服务都是模拟的。
EDIT2 我不确定我之前尝试了什么,但我上面的代码不起作用!所以我回到第一点 - 如何将服务注入测试?
【问题讨论】: