角度测试无法读取未定义的属性“名称”

时间:2018-10-31 14:58:54

标签: angular unit-testing karma-runner

我有一个ModalComponent,它通过@Input接受父级的一些属性。

这会导致测试问题

  

TypeError:无法读取未定义的属性“名称”

在ngOnInit中使用了名称,该名称应来自@Input displayeddata

如何在单元测试中通过?

目前我的测试看起来如此

beforeEach(async(() => {
        TestBed.configureTestingModule({
            declarations: [ModalComponent, FilterComponent],
            imports: [ReactiveFormsModule, TranslateModule]
        })
            .compileComponents();
    }));

    beforeEach(async () => {
    fixture = TestBed.createComponent(ModalComponent);
    component = fixture.componentInstance;
    component.displayeddata = {
        name: 'One component',
        caption: 'Caption',
        componentName: 'TextareaComponent'
    };
    fixture.detectChanges();
});

it('should create', async () => {
    fixture.detectChanges();
    fixture.whenStable().then(() => {
        expect(component).toBeTruthy();
    });
});

那是我组件的一项测试,但失败了。

更新#1

这是我在console.log(this.displayeddata);上看到的内容

Object
caption: "Caption"
component: "TextareaComponent"
name: "One component"

我还稍微更改了代码(更新的代码),现在遇到了新错误TypeError: Cannot read property 'caption' of undefined

更新#2

modal.component.ts

export class ModalComponent implements OnInit {
@Input() showenpunctsnow;
@Input() displayeddata;
@Output() ComponentParametrsInputs: FormGroup = this.fb.group({
        name: ['', Validators.required],
        caption: ['', Validators.required],
        component: ['']
    });
constructor(private fb: FormBuilder) {}
ngOnInit() {

        console.log(this.displayeddata);

        this.ComponentParametrsInputs = this.fb.group({
            name: [this.displayeddata.name, Validators.required],
            caption: [this.displayeddata.caption, Validators.required],
            component: [this.displayeddata.componentName]
        });
    }

3 个答案:

答案 0 :(得分:2)

即使在此问题已经解决的情况下,只要在这里发表评论,就可以解决其他问题。

问题最有可能来自html文件,而不是单元测试或组件本身。

在您的html文件中:

  • 转到您使用{variable}.name的地方
  • 在相应的div部分中,否则添加*ngIf="{variable}"

这应该检查该变量是否首先存在。 然后在您的单元测试中,只需执行以下操作:

it('should create', ()=> {
   expect(component).toBeTruthy();
}

如果要查看组件是否将加载指定的name

it('should create with specified name', () => {
   component.{variable}.name = 'Foo'

   fixture.detectChanges();
   expect(fixture.debugElement.nativeElement.innerHTML)
    .toContain(component.{variable}.name)
}

答案 1 :(得分:0)

您的方法很好,我认为由于异步,它失败了。试试这个:

it('should create', () => {
    component.displayeddata = {
        name: 'One component',
        caption: 'Caption',
        component: 'TextareaComponent'
    };
    fixture.detectChanges();
    expect(component).toBeTruthy();
});

答案 2 :(得分:0)

我将此更新作为“答案”,因为它不适合评论。 :)

感谢您发布组件逻辑。有了这些信息,我有足够的能力在这里建立一个快速的stackblitz测试环境:https://stackblitz.com/edit/stackoverflow-q-53086352?file=app%2Fmy.component.spec.ts

我必须通过以下方式与您的代码略有不同:

  • FilterComponent和TranslateModule均已被注释掉,因为我没有访问该代码的权限,并且您此时尚未对其进行测试。
  • 您在第二个“ beforeEach”函数以及“ it”规范中错误地使用了“异步”功能-您没有将箭头功能包装在异步功能内,而是在使用异步保留字将功能定义为异步-异步/等待的一部分,这是完全不同的事情。在单词async之后,您需要另一组括号来将其称为angular / core / testing函数,而不是javascript保留字。 :)
  • 我添加了一个简单的模板,其中显示了displaydata变量之一

但是,令人惊讶的是,当我将您的代码放入stackblitz中时-一切正常!很显然,您遇到的问题是由到目前为止所提供的代码之外的某些代码引起的。

我对下一步的建议:

  • 要么编辑我放在一起的现有堆栈闪电战,要么将其分叉到您自己的帐户中以使用它。
  • 添加其他代码/数据,直到问题再次发生。这将指向实际错误所在的位置。

祝你好运!