【问题标题】:Template variable throwing undefined error while running jasmine test case运行 jasmine 测试用例时模板变量抛出未定义的错误
【发布时间】:2019-05-06 06:07:37
【问题描述】:

我在运行单元测试用例时遇到以下错误,

TypeError: Cannot read property 'type' of undefined

以下是我的规格,

describe('ListComponent', () => {
  let component: ListComponent;
  let fixture: ComponentFixture<ListComponent>;

  const mock = {
    "type": "list",
      "items": [
        {
          "type": "unordered-list-item",
          "text": "Unordered Item One",
          "depth": 1,
        }
      ]
  }
  cacheTestbed({
    imports: [ContentComponentsModule],

  });

  beforeEach(() => {
    fixture = TestBed.createComponent(ListComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    component.contentOnCreate(mock)
  });

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

这是我的 HTML,

<ng-container *ngIf="listItems.type==='unordered-list-item'">
  <ul *ngIf="listItems.children.length > 0" class="bw-information-ul-with-disc">
    <bw-information-recursive-list *ngFor="let child of listItems.children" [child]="child"></bw-information-recursive-list>
  </ul>
</ng-container>

listItems.type 未定义。如果我评论 html 代码,所有测试用例都会通过。

我什至尝试将模拟值分配给 beforeEach 内的 listItems,但如果出现同样的错误,它就不起作用了。

请帮忙。

*********** 更新 *******

我的组件规格

Component.Ts

export class ListComponent {
  public listItems: RecursiveList;

  contentOnCreate(values: ListItems): void {
    this.listItems = this.createListTree(values.items);
  }

  createListTree(listItem: ListItem[]): Item {
    const root: Item = { text: 'root', children: [], type: listItem[0].type }
    const stack: Item[] = []
    const firstChildOfRoot = {
      text: listItem[0].text,
      children: [],
      type: listItem[0].type
    }
    root.children.push(firstChildOfRoot)
    stack.push(root)
    stack.push(firstChildOfRoot)

    for (let i = 1; i < listItem.length; i++) {
      const flatItem = listItem[i]
      const depthDiff = flatItem.depth - (stack.length - 1)
      if (depthDiff <= 0) {
        this.removeFromEnd(stack, -depthDiff + 1)
      }
      const stackTop = stack[stack.length - 1]
      const newEl = {
        text: flatItem.text,
        children: [],
        type: flatItem.type
      }
      stackTop.children.push(newEl)
      stack.push(newEl)
    }
    return root
  }

  removeFromEnd<T>(array: T[], count: number) {
    array.splice(array.length - count, count)
  }
}

【问题讨论】:

  • 贴出组件的代码,贴出你试过的代码。
  • 我已经更新了我的问题
  • contentOnCreate() 方法应该在 调用 detectChanges() 之前调用。但这无论如何说明了组件中的一个设计问题:当组件实际在应用程序中使用时,什么时候会调用这个 contentOnCreate() 方法?只有在第一次呈现模板之前已经初始化了 listItems 时,您的模板才有效,而且它似乎没有,因此您需要在尝试访问其类型之前测试 listItems 是否已定义。
  • @stacks 我通过投入时间提供了答案。如果您提供意见以感谢我的努力,那真的很有意义

标签: angular jasmine karma-jasmine


【解决方案1】:

尝试在component.contentOnCreate 之后移动fixture.detectChanges();

  beforeEach(() => {
    fixture = TestBed.createComponent(ListComponent);
    component = fixture.componentInstance;
    component.contentOnCreate(mock)
    fixture.detectChanges();
  });

【讨论】:

    猜你喜欢
    • 2014-11-10
    • 2019-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-15
    • 1970-01-01
    • 2020-06-29
    相关资源
    最近更新 更多