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

Ser*_*gey 17 unit-testing karma-runner angular

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

这会导致测试出现问题

类型错误:无法读取未定义的属性“名称”

名称在 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();
    });
});
Run Code Online (Sandbox Code Playgroud)

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

更新 #1

这是我的意思 console.log(this.displayeddata);

Object
caption: "Caption"
component: "TextareaComponent"
name: "One component"
Run Code Online (Sandbox Code Playgroud)

我也稍微改变了我的代码(更新的代码),现在出现了一个新错误 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]
        });
    }
Run Code Online (Sandbox Code Playgroud)

小智 19

只是要在这里发表评论,即使这已经解决了,以防其他人遇到同样的问题。

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

在您的 html 文件中:

  • 转到您正在使用的地方 {variable}.name
  • 在相应的部分、div 中或以其他方式添加 *ngIf="{variable}"

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

it('should create', ()=> {
   expect(component).toBeTruthy();
}
Run Code Online (Sandbox Code Playgroud)

如果你想然后检查组件是否会加载指定的name

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

   fixture.detectChanges();
   expect(fixture.debugElement.nativeElement.innerHTML)
    .toContain(component.{variable}.name)
}
Run Code Online (Sandbox Code Playgroud)


dmc*_*dle 5

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

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

我必须通过以下方式稍微偏离上面的代码:

  • FilterComponent 和 TranslateModule 都被注释掉了,因为我无权访问该代码,并且您此时也没有测试它们。
  • 您在第二个“beforeEach”函数以及“it”规范中错误地使用了“async” - 您没有将箭头函数包装在异步内,而是使用异步保留字将函数定义为异步 - 部分async/await,这是完全不同的事情。您需要在 async 一词后面加上另一组括号,才能将其称为 Angular/Core/testing 函数,而不是 javascript 保留字。:)
  • 我添加了一个简单的模板,用于显示显示数据变量之一

然而,令人惊讶的是,当我将你的代码放入 stackblitz 时 - 一切都运行得很好!很明显,您遇到的问题是由一些超出您目前所提供内容的代码引起的。

我对后续步骤的建议:

  • 要么编辑我放在一起的现有 stackblitz,要么将其分叉到您自己的帐户来使用它。
  • 添加额外的代码/数据,直到问题再次出现。这将指出实际错误所在。

祝你好运!


Eni*_*ima 1

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

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