使用Aurelia进行测试时,服务不会被嘲笑

时间:2017-09-28 02:36:08

标签: phantomjs aurelia jest

我试图在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两次,那么我可能会为同一个班级获得两个不同的密钥...但我无法看到这将如何发生或如何解决它。

非常感谢您的帮助!

EDIT! 感谢@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 我不确定我之前尝试过的是什么,但上面的代码不起作用!所以我回到原点 - 如何将服务注入测试?

1 个答案:

答案 0 :(得分:1)

刚刚查看过,在我看来你在注册Mock实例之前从容器中请求了Communications实例。

我没有足够的时间来测试正确的解决方案(如果你提供了一个要点已经为你修改过的那个)。但是,如果您已经使用容器来获取视图模型,那么您是否可以将这些行移到class Whatever(object): def __init__(self): self.ap = np.float64(0.0) self.awx = np.float64(0.0) self.aex = np.float64(0.0) self.rhs = np.float64(0.0) def bc_neumann(self, i,m,nx): m[0] = int(i) m[1] = int(i-1) m[2] = int(i+1) if i == 0: m[1] = nx - 1 self.ap = self.ap + self.awx self.awx = 0.0 if i == nx-1: m[2] = 0 self.ap = self.ap + self.aex self.aex = 0.0 return m w = Whatever() w.bc_neumann(1, [], 42) 之上以进行制作:

container.get