Angular/TypeScript: snackbar 的单元测试调用

Angular/TypeScript: Unit Test call of snackbar

我有一个使用 MatSnackBar 的方法 onDelete,它像这样被注入到构造函数中:

constructor(private todoListService: TodolistService, private snackBar: MatSnackBar) { }

onDelete(todoList: TodoList): void {
    const deletedTodoListName = todoList.name;
    this.todoListService.delete(todoList).subscribe(response => {
      this.loadTodoLists();

      this.snackBar.open(`${deletedTodoListName} wurde gelöscht`, 'Schliessen', {
        duration: 3000,
        horizontalPosition: 'center',
        verticalPosition: 'bottom',
      });
    });
  }

我尝试对这个方法进行单元测试:

import { async, ComponentFixture, TestBed, inject, getTestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

import { NavigationviewComponent } from './navigationview.component';
import { TodolistService } from '../todolist.service';
import { MatSnackBarModule, MatSnackBar } from '@angular/material/snack-bar';
import { TodoList } from '../todolist';
import { Observable } from 'rxjs';

describe('NavigationviewComponent', () => {
  let injector: TestBed;
  let component: NavigationviewComponent;
  let fixture: ComponentFixture<NavigationviewComponent>;
  let httpMock: HttpTestingController;
  let todoListService: TodolistService;
  let snackBar: MatSnackBar;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ HttpClientTestingModule, MatSnackBarModule  ],
      declarations: [ NavigationviewComponent ],
      providers: [ TodolistService, MatSnackBar ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    injector = getTestBed();
    httpMock = injector.inject(HttpTestingController);
    todoListService = injector.inject(TodolistService);
    snackBar = injector.inject(MatSnackBar);
    fixture = TestBed.createComponent(NavigationviewComponent);
    fixture.detectChanges();
    component = fixture.componentInstance;
  });

  afterEach(() => {
    httpMock.verify();
  });

it('should delete the todolist when onDelete is called', () => {
    const todoList: TodoList = { name: 'todoList', listItems: [] };
    spyOn(todoListService, 'delete').and.returnValue(new Observable<object>());
    spyOn(snackBar, 'open');

    component.onDelete(todoList);

    expect(snackBar.open).toHaveBeenCalled();
    const req = httpMock.expectOne('https://angulareinfuehrungsaufgabetodolistapi.azurewebsites.net/todolist');
    expect(req.request.method).toBe('GET');
  });
});

但是执行测试的时候,提示

Expected spy open to have been called.

为什么测试无法识别对 snackBar 的调用? 通过删除项目执行代码时,小吃栏可见。

提前致谢

我觉得你的spyOntodoListService'delete不准确。

试试这个:

import { of } from 'rxjs';
.....
spyOn(todoListService, 'delete').and.returnValue(of(null)); // it's up to you what you want to return

component.onDelete(todoList);

expect(snackBar.open).toHaveBeenCalled();