簡體   English   中英

在Angular(7+)中測試可選的構造函數參數

[英]Test optional constructor parameter in Angular (7+)

我有問題,將不勝感激。

我們有一個帶有構造函數的服務,該構造函數使用可選的參數,例如

@Injectable()
export class OurService {
    constructor(
        private someService: SomeService,
        @Optional() someOption: SomeOption,
    ) {
        if(someOption) {
            this.someService.doSomethingWith(someOption);
        }
        // ...do other things
    }
    // ...other methods
}

現在,我想測試一下並獲得良好的覆蓋,這意味着需要進行一些測試,其中OurService一次實例化,另一次沒有someOption實例化,而且我希望可以調用someService.doSoemthingWith。

我通常像這樣設置我的測試模塊

let service: OurService;
let someService: SomeService;

beforeEach(async(() => {
    TestBed.configureTestingModule({
        imports: [],
        declarations: [],
        providers: [
            { provide: SomeService, useClass: MockSomeService },
        ],
    }).compileComponents();
}));

beforeEach(() => {
    service = TestBed.get(AuthService);
    someService = TestBed.get(SomeService);
});

現在,我很難嘗試正確完成所有測試。 我該如何測試這三件事?

  • 提供someOption時應調用someService
  • 未提供someOption時不應調用someService
  • 應該測試其他東西

這是我的嘗試(在其他嘗試中):

  1. 安裝間諜並查看是否已調用方法

     it('blabla', () => { spyOn(someService, 'doSomethingWith'); // I guess the spy is too late because TestBed get already called the constructor expect(someService.doSomethingWith).toHaveBeenCalled(); }); 
  2. 嘗試為此測試添加提供程序

     it('blabla', () => { spyOn(someService, 'doSomethingWith'); TestBed.overrideProvider(SomeOption, { useValue: MockSomeOption }); // MockSomeOption is defined somewhere TestBed.compileComponents(); service = TestBed.get(SomeService); // does not work expect(someService.doSomethingWith).toHaveBeenCalled(); }); 
  3. 注入smeOption(不知道如何,因此此代碼是正確的)

     it('blabla', inject([SomeService], (someService: SomeService) => { //const injector = Injector.create({ providers: [{ provide: SomeOption, useValue: MockSomeOption }] }); spyOn(someService, 'doSomethingWith'); // ?? what now ?? expect(someService.doSomethingWith).toHaveBeenCalled(); }); 
  4. 像這樣將一些選項添加到TestBed設置

     beforeEach(async(() => { TestBed.configureTestingModule({ imports: [], declarations: [], providers: [ { provide: SomeService, useClass: MockSomeService }, { provide: SomeOption, useClass: MockSomeOption }, ], }).compileComponents(); })); // problem now is that it is always provided. and I can not test the else-path 

如何按大多數測試的要求設置一次服務,然后在一個測試中添加someOption並再次調用構造函數,以便我的間諜可以執行其秘密間諜活動?

我不確定這是否正是您想要的,但是您可以嵌套describe ...

describe('Our Service Tests', () => {

    describe('Given an optional parameter', () => {
        beforeEach(async(() => {
            TestBed.configureTestingModule({
                imports: [],
                declarations: [],
                providers: [
                    { provide: SomeService, useClass: MockSomeService },
                    { provide: SomeOption, useClass: MockSomeOption },
                ],
           }).compileComponents();
        }));

        // Tests with the optional parameters
    });

    describe('Given no optional parameter', () => {
        beforeEach(async(() => {
            TestBed.configureTestingModule({
                imports: [],
                declarations: [],
                providers: [
                    { provide: SomeService, useClass: MockSomeService },
                ],
            }).compileComponents();
        }));

        // Tests not using the optional parameter
    });

});

如果我只有一個或兩個需要獨特設置的測試,我通常會跳過為這些測試創建描述的過程。 相反,我將為大多數測試創建一個帶有默認設置的嵌套描述,然后將唯一的測試添加到外部描述中,並使它們各自進行自己的設置。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM