【问题标题】:Service not being mocked when testing with Aurelia使用 Aurelia 进行测试时服务没有被嘲笑
【发布时间】: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 我不确定我之前尝试了什么,但我上面的代码不起作用!所以我回到第一点 - 如何将服务注入测试?

【问题讨论】:

    标签: phantomjs aurelia jestjs


    【解决方案1】:

    刚刚查看了一下,在我看来,您是在注册 Mock 实例之前从容器中请求 Communications 实例。

    我没有足够的时间来测试正确的解决方案(如果你提供了一个要点,我已经为你修改了它)。但是鉴于您已经在使用容器来获取您的视图模型,您能否将这些行移到 container.get 上方来制作:

    container.registerInstance(RoundService, roundService);
    container.registerInstance(CommunicationService, service);
    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"));
    });
    

    【讨论】:

    • 不完全是,事实上这阻止了我的简单expect(true).toBe(true); 测试工作。但是,您让我走上了尝试在 container.get 之后重新排序注册的正确轨道,并且我对我的问题进行了编辑(给我一点时间来写它)。既然您向我指出了那里,如果您更新答案,很高兴将其标记为已接受。
    • As I mentioned in gitter 我不明白你的解决方案是如何工作的,所以我不想更新我不理解的答案。我不确定为什么我的解决方案也不起作用。
    猜你喜欢
    • 2015-06-06
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    • 1970-01-01
    • 1970-01-01
    • 2012-10-03
    相关资源
    最近更新 更多