首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >角度测试-模拟InjectionToken

角度测试-模拟InjectionToken
EN

Stack Overflow用户
提问于 2018-10-02 19:21:57
回答 1查看 10.2K关注 0票数 9

我正在尝试测试一个处理SignalR连接的Angular服务,它将SignalR的代码作为InjectionToken。

下面是提供程序文件:

代码语言:javascript
复制
// signalr-provider.ts

import { InjectionToken } from '@angular/core';

export const SIGNALR_TOKEN = new InjectionToken('signalR');

export function signalRFactory() {
    return window['signalR'];
}

export const SIGNALR_PROVIDER = [ { provide: SIGNALR_TOKEN, useFactory: signalRFactory } ];

这就是服务:

代码语言:javascript
复制
// signalr-service.ts

import { Injectable, Inject } from '@angular/core';

import { SIGNALR_TOKEN } from './signalr-provider';
import { HubConnection } from '@aspnet/signalr';
import { environment } from '../../../environments/environment';

@Injectable()
export class SignalrService {
    private hubConnection: HubConnection;
    private baseUrl: string = environment.baseUrl;

    constructor(@Inject(SIGNALR_TOKEN) private signalR: any) {
        this.init();
    }

    init(): void {
        this.hubConnection = new this.signalR.HubConnectionBuilder().withUrl(`${this.baseUrl}/hubs/test`).build();
    }
}

令牌在app模块中提供,如下所示:

代码语言:javascript
复制
// From app.module.ts

@NgModule({
    declarations: [...],
    imports: [...],
    providers: [ SIGNALR_PROVIDER, SignalrService ],
    bootstrap: [ AppComponent]
})
export class AppModule {}

到目前为止,我还没有在我的测试文件中模拟InjectionToken,每次都会得到一条NullInjectorError: No provider for InjectionToken signalR!消息。

这是我的第一次尝试,从signalRFactory函数返回一个模拟对象,其中只包含初始连接所需的属性:

代码语言:javascript
复制
// signalr-service.spec.ts

import { TestBed, async } from '@angular/core/testing';
import { InjectionToken } from '@angular/core';

import { SignalrService } from './signalr-service';

const SIGNALR_TOKEN = new InjectionToken('signalR');

function signalRFactory() {
    return {
        HubConnectionBuilder: () => {
            return {
                withUrl: (url) => {
                    return {
                        build: () => {}
                    };
                }
            };
        }
    };
}

const SIGNALR_PROVIDER = [ { provide: SIGNALR_TOKEN, useFactory: signalRFactory } ];

describe('ConnectionService', () => {
    beforeEach(
        async(() => {
            TestBed.configureTestingModule({
                providers: [ SIGNALR_PROVIDER, SignalrService ]
            });
        })
    );

    it('should exist', () => {
        const connectionService = TestBed.get(SignalrService);
        expect(connectionService).toBeTruthy();
    });
});

在我的第二次尝试中,我将模拟对象赋给了一个变量:

代码语言:javascript
复制
import { TestBed, async } from '@angular/core/testing';
import { InjectionToken } from '@angular/core';

import { SignalrService } from './signalr-service';

const SIGNALR_TOKEN = new InjectionToken('signalR');

const SIGNALR_VALUE = {
    HubConnectionBuilder: () => {
        return {
            withUrl: (url) => {
                return {
                    build: () => {}
                };
            }
        };
    }
};

const SIGNALR_PROVIDER = [ { provide: SIGNALR_TOKEN, useValue: SIGNALR_VALUE } ];

describe('ConnectionService', () => {
    beforeEach(
        async(() => {
            TestBed.configureTestingModule({
                providers: [ SIGNALR_PROVIDER, SignalrService ]
            });
        })
    );

    it('should exist', () => {
        const connectionService = TestBed.get(SignalrService);
        expect(connectionService).toBeTruthy();
    });
});

在我的第三次尝试中,我取出了SIGNALR_PROVIDER,并尝试按工厂和直接值在提供程序数组中直接提供值:

直接值:

代码语言:javascript
复制
import { TestBed, async } from '@angular/core/testing';
import { InjectionToken } from '@angular/core';

import { SignalrService } from './signalr-service';

const SIGNALR_TOKEN = new InjectionToken('signalR');

const SIGNALR_VALUE = {
    HubConnectionBuilder: () => {
        return {
            withUrl: (url) => {
                return {
                    build: () => {}
                };
            }
        };
    }
};

describe('ConnectionService', () => {
    beforeEach(
        async(() => {
            TestBed.configureTestingModule({
                providers: [ { provide: SIGNALR_TOKEN, useValue: SIGNALR_VALUE }, SignalrService ]
            });
        })
    );

    it('should exist', () => {
        const connectionService = TestBed.get(SignalrService);
        expect(connectionService).toBeTruthy();
    });
});

工厂:

代码语言:javascript
复制
import { TestBed, async } from '@angular/core/testing';
import { InjectionToken } from '@angular/core';

import { SignalrService } from './signalr-service';

const SIGNALR_TOKEN = new InjectionToken('signalR');

function signalRFactory() {
    return {
        HubConnectionBuilder: () => {
            return {
                withUrl: (url) => {
                    return {
                        build: () => {}
                    };
                }
            };
        }
    };
}

describe('ConnectionService', () => {
    beforeEach(
        async(() => {
            TestBed.configureTestingModule({
                providers: [ { provide: SIGNALR_TOKEN, useFactory: signalRFactory }, SignalrService ]
            });
        })
    );

    it('should exist', () => {
        const connectionService = TestBed.get(SignalrService);
        expect(connectionService).toBeTruthy();
    });
});

每一次尝试都会给我NullInjectorError: No provider for InjectionToken signalR!我卡住了。很明显,关于InjectionToken有一些我不知道的事情。有谁能给我指个方向吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-10 21:13:13

解决了这个问题--我的问题是我在测试文件中重新定义了令牌,所以我的测试为我的模拟对象提供了一个与我的服务期望的令牌完全不同的令牌。将其更改为以下内容即可解决此问题:

代码语言:javascript
复制
// signalr-service.spec.ts

import { TestBed, async } from '@angular/core/testing';
import { InjectionToken } from '@angular/core';

import { SignalrService } from './signalr-service';

import { SIGNALR_TOKEN } from './signalr-provider'; // This is the change

function signalRFactory() {
    return {
        HubConnectionBuilder: () => {
            return {
                withUrl: (url) => {
                    return {
                        build: () => {}
                    };
                }
            };
        }
    };
}

const SIGNALR_PROVIDER = [ { provide: SIGNALR_TOKEN, useFactory: signalRFactory } ];

describe('ConnectionService', () => {
    beforeEach(
        async(() => {
            TestBed.configureTestingModule({
                providers: [ SIGNALR_PROVIDER, SignalrService ]
            });
        })
    );

    it('should exist', () => {
        const connectionService = TestBed.get(SignalrService);
        expect(connectionService).toBeTruthy();
    });
});
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52607342

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档