Angular Testing : How to provide configuration object to service class with TestBed?

标签 angular unit-testing testing jasmine

我有一个 Angular 服务需要将配置对象传递给该服务:

// my.module.ts
@NgModule({ ... })
export class MyModule {
    static forRoot(config: MyServiceConfig): ModuleWithProviders {
        return {
            ngModule: MyModule,
            providers: [{ provide: MyServiceConfig, useValue: config }],
        };
    }
}


//my.service.ts
export class MyService {
        constructor(private _http: HttpClient, @Optional() config: MyServiceConfig) {
        if (config) {
            if (!config.attr1) {
                throw new Error('You must provide the attr1 to use this Module.');
            } else if (!config.attr2) {
                throw new Error('You must provide the attr2 to use this Module.');
            } else {
                this.attr1 = config.attr1;
                this.attr2 = config.attr2;
            }
        } else {
            throw new Error(
                'You must provide a MyServiceConfig object with the attr1 and the attr2 to use this module.',
            );
        }
    }

}

一切正常,但我想围绕向服务提供该配置对象编写几个测试。我在测试文件中有以下 beforeEach,当未提供配置对象时,它会按预期抛出错误:

beforeEach(() => {
    TestBed.configureTestingModule({
        imports: [HttpClientTestingModule],
        providers: [FeedbackService],
    });
});

但是当我试图将其从 beforeEach 移出并进入单独的测试时,我无法正确抛出错误。如果完全按照上面的方式调用它,但在测试中,它将:

it('should do something', () => {
    TestBed.configureTestingModule({
        imports: [HttpClientTestingModule],
        providers: [FeedbackService],
    });
});

我在 try/catch block 中尝试了上述操作,试图捕获错误,但它给了我一个误报。我尝试了 expect(() => {}).toThrowError()toThrow() 方法,但即使将 TestBed.configureTestingModule() 在 expect 中的那个箭头函数中不起作用。这样做不会引发错误。

有没有办法做到这一点?另外,有没有办法向服务提供配置对象以测试它是否将服务属性设置为正确的值?

最佳答案

只需为配置对象提供一个值:

describe("FeedbackService", ()=>{
    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [HttpClientTestingModule],
            providers: [FeedbackService]
        });
    });

    describe("when config object is provided", ()=>{
        let dummyConfig : Object;
        beforeEach(()=>{
          dummyConfig = {/* set some properties*/};
          TestBed.overrideProvider(MyServiceConfig, {useValue: dummyConfig});
        });

        it("should not explode", ()=>{
          // a test in which the config object is dummyConfig
        });
    });
});

旁注:我看不到用 @Optional 装饰配置对象的意义,并在没有提供 token 值时抛出异常。您基本上是在重新实现默认的未提供逻辑。

关于 Angular Testing : How to provide configuration object to service class with TestBed?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55067940/

相关文章:

c# - 一个类中的测试是否保证不会同时执行?

python - 如何使用模拟在 python 中写入和读取模拟文件对象?

php - require_once(PHP/CodeCoverage/Filter.php) : failed to open stream

angular - 在 AGM map 之前加载 googlemaps api

angular - 尝试使用 SafePipe 清理嵌入的 Youtube 视频时出错

angular - 错误 : Uncaught (in promise): Response with status: 404 Not Found for URL in angular 2

testing - Jmeter OS 进程采样器

android - ionic cordova 构建 android 由于 AOT 而失败

unit-testing - 'too simple to break' 有多简单? - 解释

javascript - 如何通过模拟选择器和/或 redux 存储来编写 Redux Saga 测试