【发布时间】:2020-03-26 12:08:53
【问题描述】:
我有一个组件,它依赖于一个服务,它也有一些依赖关系。 (组件调用 service 方法,并使用 subject 获取 observable。)
组件:
export class CoursesComponent implements OnInit {
courses: Observable<Course[]>;
constructor(private courseService: CourseService) {
this.courseService.loadCourses();
}
ngOnInit(): void {
this.courses = this.courseService.course;
}
}
服务
@Injectable()
export class CourseService {
private courseSubject: Subject<Course[]> = new Subject();
course = this.courseSubject.asObservable();
constructor(private courseApiService: CourseApiService,
private router: Router,
private route: ActivatedRoute) { }
loadCourses(title?: string, end?: number): Subscription {
return this.getCourses(title, end).subscribe((courses: Course[]) => this.courseSubject.next(courses));
}
private getCourses(title?: string, end?: number): Observable<Course[]> {
return this.courseApiService.getCourses(title, end);
}
}
我尝试测试组件但遇到了麻烦:我不想向 TestBed 注入真正的服务,所以一开始我试图监视所有 courseService 方法:
const courseServiceMethods = [
'loadCourses',
'postCourse',
'editCourse',
'getCourseById',
'removeCourseById',
'navigateById'];
describe('CoursesComponent', () => {
let component: CoursesComponent;
let fixture: ComponentFixture<CoursesComponent>;
let courseService: SpyObj<CourseService>;
beforeEach(async(() => {
courseService = jasmine.createSpyObj('CourseService', courseServiceMethods);
TestBed.configureTestingModule({
declarations: [ CoursesComponent, SearchComponent ],
providers: [
{provide: CourseService, useValue: courseService},
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(CoursesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
describe('onDelete()', () => {
it('should call removeCourseById()', () => {
component.onDelete('2');
expect(courseService.removeCourseById).toHaveBeenCalled();
});
});
但是使用这种方法,我只能检查是否调用了服务中的某些方法,并且无法观察到这给了我数据。 所以我有另一个选择:在 spec.ts 中为 course.service 编写我自己的模拟类并在 TestBed 中提供它:
@Injectable()
class Mock {
private courseSubject: Subject<Course[]> = new Subject();
course = this.courseSubject.asObservable();
loadCourses(title?: string, end?: number): Subscription {
return this.getCourses(title, end).subscribe((courses: Course[]) => this.courseSubject.next(courses));
}
private getCourses(title?: string, end?: number): Observable<Course[]> {
return of(coursesMockArray);
}
}
但是使用这个选项我必须模拟 courseService 中的所有方法,如果它太大了? 是否有机会从课程服务中窥探方法并检查返回数据?
【问题讨论】:
标签: angular unit-testing jasmine spy