Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度测试:如何使用测试床向服务类提供配置对象?_Angular_Unit Testing_Testing_Jasmine - Fatal编程技术网

Angular 角度测试:如何使用测试床向服务类提供配置对象?

Angular 角度测试:如何使用测试床向服务类提供配置对象?,angular,unit-testing,testing,jasmine,Angular,Unit Testing,Testing,Jasmine,我有一个Angular服务,需要将配置对象传递到该服务: // my.module.ts @NgModule({ ... }) export class MyModule { static forRoot(config: MyServiceConfig): ModuleWithProviders { return { ngModule: MyModule, providers: [{ provide: MyServiceCo

我有一个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.',
            );
        }
    }

}
这一切都是可行的,但是我想写一些测试来为服务提供配置对象。在测试文件中,我在每个之前都有以下
,当没有提供config对象时,它会像预期的那样抛出一个错误:

beforeEach(() => {
    TestBed.configureTestingModule({
        imports: [HttpClientTestingModule],
        providers: [FeedbackService],
    });
});
但是,当我试图在每次测试之前将其从
中移出并放入单个测试时,我无法正确抛出错误。如果完全按照上述方法调用,但在测试中调用,则会:

it('should do something', () => {
    TestBed.configureTestingModule({
        imports: [HttpClientTestingModule],
        providers: [FeedbackService],
    });
});
我在
try/catch
块中尝试了上述操作,试图捕捉错误,但它给出了一个假阳性。我尝试了
expect(()=>{}).tothrower()
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
和throw装饰配置对象有什么意义。您基本上是在重新实现默认的未提供逻辑。

我使用了@Jota.Toledo的一些答案,并对其进行了编辑,以获得以下测试文件:

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

import { MyService } from './my.service';
import { MyServiceConfig } from './my-service-config';

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

    describe('config object provided', () => {
        let config: MyServiceConfig;
        const attr1 = 'https://my-test-api.test.com';
        const attr2 = 'testing';

        beforeEach(() => {
            config = null;
        });

        it('should use the values passed in the config for the attr1 and attr2', () => {
            config = { attr1, attr2 };
            TestBed.overrideProvider(MyService, { useFactory: () => new MyService(null, config) });
            const service: MyService = TestBed.get(MyService);

            expect(service.attr1).toBe(attr1);
            expect(service.attr2).toBe(attr2);
        });

        it('should throw an error if config object is provided but not the attr1 attribute', () => {
            try {
                config = { attr1: null, attr2 };
                TestBed.overrideProvider(MyService, { useFactory: () => new MyService(null, config) });
                const service: MyService = TestBed.get(MyService);
            } catch (e) {
                expect(e.message).toBe('You must provide the api URL to use this module.');
            }
        });

        it('should throw an error if config object is provided but not the attr2 attribute', () => {
            try {
                config = { attr1, attr2: null };
                TestBed.overrideProvider(MyService, { useFactory: () => new MyService(null, config) });
                const service: MyService = TestBed.get(MyService);
            } catch (e) {
                expect(e.message).toBe('You must provide the feedback source to use this module.');
            }
        });
    });

    describe('config object not provided', () => {
        beforeEach(() => {
            TestBed.overrideProvider(MyService, { useFactory: () => new MyService(null, null) });
        });
        it('should throw an error if no config object provided', () => {
            try {
                const service: MyService = TestBed.get(MyService);
            } catch (e) {
                expect(e.message).toBe(
                    'You must provide a MyServiceConfig object with the attr1 and the attr2 to use this module.',
                );
            }
        });
    });
});

这正确地抛出了应该抛出的错误,并且我能够检查message属性以确保它在正确的时间抛出了正确的错误。

我尝试了您的解决方案,但仍然得到相同的错误。关于
@可选的
装饰器,您有一个很好的观点。我读过的所有教程都有,我不确定如何要求它,但是删除decorator似乎会给我同样的错误,所以我确实删除了它。以下工作:
TestBed.overrideProvider(FeedbackService,{useFactory:()=>newfeedbackservice(null,config)})我为HttpClient传递了null,因为我没有测试HTTP调用。您如何用可注入的?介意添加这部分代码吗?我不喜欢你目前的做法。