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 的调用?
通过删除项目执行代码时,小吃栏可见。
提前致谢
我觉得你的spyOn
todoListService
'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();
我有一个使用 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 的调用? 通过删除项目执行代码时,小吃栏可见。
提前致谢
我觉得你的spyOn
todoListService
'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();