Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.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 Jasmine单元测试中:Can';t解析TestFormInputComponentBase的所有参数_Angular_Unit Testing_Dependency Injection_Jasmine_Mocking - Fatal编程技术网

Angular Jasmine单元测试中:Can';t解析TestFormInputComponentBase的所有参数

Angular Jasmine单元测试中:Can';t解析TestFormInputComponentBase的所有参数,angular,unit-testing,dependency-injection,jasmine,mocking,Angular,Unit Testing,Dependency Injection,Jasmine,Mocking,我是新来单元测试Angular应用程序的,我正在尝试测试我的第一个组件。实际上,我正在尝试测试一个抽象基类,它被实际的组件使用,所以我在我的规范中基于它创建了一个简单的组件,我正在使用它来测试它。 但是有一个依赖项需要处理(Injector),我没有正确地将其删除,因为当我尝试运行测试时,我会遇到以下错误: 无法解析TestFormInputComponentBase的所有参数 但我不确定我错过了什么? 以下是规格: import { GenFormInputComponentBase } fr

我是新来单元测试Angular应用程序的,我正在尝试测试我的第一个组件。实际上,我正在尝试测试一个抽象基类,它被实际的组件使用,所以我在我的规范中基于它创建了一个简单的组件,我正在使用它来测试它。 但是有一个依赖项需要处理(
Injector
),我没有正确地将其删除,因为当我尝试运行测试时,我会遇到以下错误:

无法解析TestFormInputComponentBase的所有参数

但我不确定我错过了什么? 以下是规格:

import { GenFormInputComponentBase } from './gen-form-input-component-base';
import { Injector, Component } from '@angular/core';
import { TestBed } from '@angular/core/testing';

// We cannot test an abstract class directly so we test a simple derived component
@Component({
    selector: 'test-form-input-component-base'
})
class TestFormInputComponentBase extends GenFormInputComponentBase {}

let injectorStub: Partial<Injector>;

describe('GenFormInputComponentBase', () => {
    let baseClass: TestFormInputComponentBase;
    let stub: Injector;

    beforeEach(() => {
        // stub Injector for test purpose
        injectorStub = {
            get(service: any) {
                return null;
            }
        };

        TestBed.configureTestingModule({
            declarations: [TestFormInputComponentBase],
            providers: [
                {
                    provide: Injector,
                    useValue: injectorStub
                }
            ]
        });

        // Inject both the service-to-test and its stub dependency
        stub = TestBed.get(Injector);
        baseClass = TestBed.get(TestFormInputComponentBase);
    });

    it('should validate required `field` input on ngOnInit', () => {
        expect(baseClass.ngOnInit()).toThrowError(
            `Missing 'field' input in AppFormInputComponentBase`
        );
    });
});
GenComponentBase
具有我试图剔除的依赖性

import { Injector } from '@angular/core';
import { LanguageService } from 'app/shared/services';

declare var $: any;

export abstract class GenComponentBase {
    protected languageService: LanguageService;

    constructor(injector: Injector) {
        this.languageService = injector.get(LanguageService);
    }

    l(key: string, ...args: any[]) {
        return this.languageService.localize(key, args);
    }
}
任何帮助都将不胜感激。谢谢

更新:

通过向
TestFormInputComponentsBase
添加构造函数,我可以删除
LanguageService
,它可以像那样正常工作。但是如果我尝试删除
注入器
,它将被忽略,并且它仍然尝试使用真正的注入器

@Component({})
class TestFormInputComponent extends GenesysFormInputComponentBase {
    constructor(injector: Injector) {
        super(injector);
    }
}

describe('GenesysFormInputComponentBase (class only)', () => {
    let component: TestFormInputComponent;

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                TestFormInputComponent,
                {
                    provide: Injector,
                    useObject: {}
                }
            ]
        });

        component = TestBed.get(TestFormInputComponent);
    });

    it('should validate required field inputs on ngOnInit', () => {
        expect(() => component.ngOnInit()).toThrowError(
            `Missing 'field' input in GenesysFormInputComponentBase.`
        );
    });
});
由于提供的模拟/存根注入器是一个空对象,我希望得到一些错误。但我从真正的注入器中得到一个错误。喷油器是否可以不被模仿

    Error: StaticInjectorError(DynamicTestModule)[LanguageService]: 
    StaticInjectorError(Platform: core)[LanguageService]: 
    NullInjectorError: No provider for LanguageService!

您想要测试
GenFormInputComponentBase
,那么为什么不在没有
testforminputcomponentbase的情况下测试它呢

   TestBed.configureTestingModule({
        declarations: [
            GenFormInputComponentBase,
        ],
        providers: [
          {
                provide: LanguageService,
                useValue: {}
          }
        ]
    });
或者使用LanguageService providers,看起来像:

        providers: [
          LanguageService,
          {
                provide: Injector,
                useValue: {}
          }
        ]

有许多不同的方法可以实现这一点,但您可以在TestFormInputComponent中对
super()
的调用中将其存根,如下所示:

class TestFormInputComponent extends GenFormInputComponentBase {
      constructor() {
          let injectorStub: Injector = { get() { return null } };
          super(injectorStub);
    }
}
此外,您还需要更改测试函数中抛出的错误的方式。请参阅详细讨论。正如您在讨论中所看到的,也有很多方法可以做到这一点,下面是一个使用匿名函数的简单方法:

it('should validate required `field` input on ngOnInit', () => {
    expect(() => baseClass.ngOnInit()).toThrowError(
        `Missing 'field' input in AppFormInputComponentBase`
    );
});
这是一个工作,显示了这种运行。我还添加了另一个测试来显示无错误的初始化


我希望这有帮助

是的,如果类没有
@injectable()
装饰器,那么编写
构造函数(){}
并在构造函数中调用
super()
可以解决这个问题

 constructor() {
    super();
}

无论我做什么,我都无法模拟
TestFormInputComponentBase
中的依赖关系。这就好像我添加的
提供者被忽略一样。我正在使用Angular提供的示例代码,但它不起作用。我在您对原始问题的更新中看到,您已经开始使用匿名函数来测试错误。:)是的,一开始我没有看到,因为测试并没有深入到执行阶段。它可以通过
测试床
删除吗?对于这种特殊的情况,这很好,因为我无论如何都需要虚拟组件来测试抽象类。但我也有几个真正的组件来扩展这些抽象基类。无法直接测试这些,必须使用类似的虚拟组件对其进行扩展。如果没有更好的选项,但它似乎应该直接与
测试床一起工作,那么它是可用的。按照您在
GenComponentBase
中使用inject的方式配置TestingModule
,您需要掌握实际的inject,以便模拟它,因为分层依赖项注入。细节。在发送之前不要嘲笑它,IDK如何在该级别获得正确的。这需要比我更有经验的人才能弄明白
 constructor() {
    super();
}