Как проверить angular компонент - PullRequest
0 голосов
/ 26 марта 2020

У меня есть компонент, который зависит от службы, которая тоже имеет некоторые зависимости. (Компонент вызова метода обслуживания и получения наблюдаемого обратно с использованием субъекта.)

Компонент:

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();
    });
  });

, но с этим методом я могу только проверьте, не вызваны ли некоторые методы из сервиса и не могут ли они быть видимыми, что дает мне мои данные. Поэтому у меня есть еще один вариант: в spe c .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, а если он слишком большой? Есть ли возможность шпионить за методами из курсовой службы и проверять возвращаемые данные?

1 Ответ

0 голосов
/ 26 марта 2020

Вы можете сделать:

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

      expect(courseService.removeCourseById).toHaveBeenCalled();
    });

Я бы выполнял подписку в компонентах, а не в службах, хотя они являются конечными наблюдаемыми, мне кажется странным, что они подписываются в службе.

...