繁体   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