Angular2:Jasmine测试失败'无法读取未定义的属性长度',好像我的类的实例没有被创建但不确定为什么

时间:2017-03-15 14:30:12

标签: angular typescript jasmine

我正在学习角度2并继续学习本教程:

Angular 2 Tutorial

对我而言,这都是因为我的Todo对象的实例由于某种原因没有被创建,所以它无法获得它的属性。我无法弄清楚为什么不会创建它。

我有一个失败的茉莉花测试,这是唯一一个失败的测试:

it('should display "Todos" in h1 tag', async(() => {
  let fixture = TestBed.createComponent(AppComponent);
  fixture.detectChanges();
  let compiled = fixture.debugElement.nativeElement;
  expect(compiled.querySelector('h1').textContent).toContain('Todos');
}));

这是我的HTML模板:

    <section class="todoapp">
  <header class="header">
    <h1>Todos</h1>
    <input class="new-todo" placeholder="What needs to be done?" autofocus="" [(ngModel)]="newTodo.title" (keyup.enter)="addTodo()">
  </header>
  <section class="main" *ngIf="todos.length > 0">
      <ul class="todo-list">
        <li *ngFor="let todo of todos" [class.completed]="todo.complete">
          <div class="view">
            <input class="toggle" type="checkbox" (click)="toggleTodoComplete(todo)" [checked]="todo.complete">
            <label>{{todo.title}}</label>
            <button class="destroy" (click)="removeTodo(todo)"></button>
          </div>
        </li>
      </ul>
  </section>
  <footer class="footer" *ngIf="todos.length > 0">
    <span class="todo-count"><strong>{{todos.length}}</strong> {{todos.length == 1 ? 'item' : 'items'}} left</span>
  </footer>
</section>

这是我的类,其中一些代码可能导致错误?

import { Component } from '@angular/core';
import { Todo } from './todo';
import { TodoDataService } from './todo-data.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers: [ TodoDataService ]
})
export class AppComponent {

  newTodo: Todo = new Todo();

  constructor(private todoDataService: TodoDataService) {
  }

  addTodo() {
    this.todoDataService.addTodo(this.newTodo);
    this.newTodo = new Todo();
  }

  toggleTodoComplete(todo) {
    this.todoDataService.toggleTodoComplete(todo);
  }

  removeTodo(todo) {
    this.todoDataService.deleteTodoById(todo.id);
  }

  getTodos() {
    return this.todoDataService.getAllTodos();
  }

}

这是Jasmine输出的一部分,我认为它试图告诉我什么是错的。

Failed: Error in ./AppComponent class AppComponent - inline template:5:24 caused by: Cannot read property 'length' of undefined
        Error: Error in ./AppComponent class AppComponent - inline template:5:24 caused by: Cannot read property 'length' of undefined

这是我的服务代码:

import { Injectable } from '@angular/core';
import { Todo } from './todo';

@Injectable()
export class TodoDataService {

  // Placeholder for last id so we can simulate
  // automatic incrementing of id's
  lastId: number = 0;

  // Placeholder for todo's
  todos: Todo[] = [];

  constructor() { }

  // Simulate POST /todos
  addTodo(todo: Todo): TodoDataService {
    if (!todo.id) {
      todo.id = ++this.lastId;
    }
    this.todos.push(todo);
    return this;
  }

  // Simulate DELETE /todos/:id
  deleteTodoById(id: number): TodoDataService {
    this.todos = this.todos.filter(todo => todo.id !== id);
    return this;
  }

  // Simulate PUT /todos/:id
  updateTodoById(id: number, values: Object = {}): Todo {
    let todo = this.getTodoById(id);
    if (!todo) {
      return null;
    }
    Object.assign(todo, values);
    return todo;
  }

  // Simulate GET /todos
  getAllTodos(): Todo[] {
    return this.todos;
  }

  // Simulate GET /todos/:id
  getTodoById(id: number): Todo {
    return this.todos.filter(todo => todo.id === id).pop();
  }

  // Toggle todo complete
  toggleTodoComplete(todo: Todo) {
    let updatedTodo = this.updateTodoById(todo.id, {
      complete: !todo.complete
    });
    return updatedTodo;
  }

}

1 个答案:

答案 0 :(得分:0)

在您的TodoComponent模板中,您指的是todos数组。但是TodoComponent上没有todos数组成员。因此,在您的模板中,待办事项将是未定义的。

 <section class="main" *ngIf="todos.length > 0">   <---  that todos doesn't exist on your component

现在,您有TodoDataService似乎封装了您的待办事项列表。因此,最有意义的是从您的Todos公开TodoDataService列表(通过返回您的待办事项列表的getTodos()方法)然后您可以使用该列表模板中的待办事项。