【问题标题】:How to test angular component如何测试角度分量
【发布时间】: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


    【解决方案1】:

    你可以这样做:

    it('should call removeCourseById()',  () => {
          spyOn(courseService.removeCourseById).and.returnValue(of(true)); // or whatever you want to mock
          component.onDelete('2');
    
          expect(courseService.removeCourseById).toHaveBeenCalled();
        });
    

    我会在组件中而不是在服务中进行订阅,尽管它们是有限的 observables,但在我看来它们在服务中被订阅很奇怪。

    【讨论】:

    • 谢谢。关于订阅服务 - 这是测试科目的一部分)
    猜你喜欢
    • 2020-04-21
    • 2013-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2019-09-22
    • 1970-01-01
    相关资源
    最近更新 更多