Angular-Testing: Как предоставить объект конфигурации для класса обслуживания с TestBed? - PullRequest
1 голос
/ 08 марта 2019

У меня есть служба 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, пытаясь отловить ошибку, но это дало мне ложный положительный результат.Я пробовал методы expect(() => {}).toThrowError() и toThrow(), но даже когда помещал TestBed.configureTestingModule() внутри этой функции стрелки в ожидаемой, не сработало.При этом не выдается ошибка.

Есть ли способ сделать это?Кроме того, есть ли способ предоставить объект конфигурации службе, чтобы проверить, что он устанавливает атрибуты службы в правильные значения?

Ответы [ 2 ]

1 голос
/ 08 марта 2019

Просто укажите значение для объекта конфигурации:

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
        });
    });
});

Sidenote: Я не вижу смысла украшать объект конфигурации с помощью @Optional и выбрасываю, когда нет значения длятокен предоставляется.По сути, вы заново реализуете логику, не предоставленную по умолчанию.

0 голосов
/ 08 марта 2019

Я использовал некоторые из ответов @ 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.',
                );
            }
        });
    });
});

Это правильно выдавало ошибки, когда предполагалось, и я смог проверить свойство сообщения дляубедитесь, что он выдал правильную ошибку в нужное время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...