Angular тест как смоделировать данные ActivatedRoute - PullRequest
1 голос
/ 14 февраля 2020

У меня очень большая проблема с имитацией свойства данных ActivatedRoute. Что бы я ни делал, все заканчивается сообщением об ошибке: Error: <spyOnProperty> : Property data does not have access type get. Перемещение заглушки const в отдельный фиктивный класс также не решает проблему. Я обнаружил, что это должно быть прямо вперед, но я борюсь с этим уже несколько дней.

Компонент

@Component({
  selector: 'app-notifications',
  templateUrl: './notifications.component.html',
  styleUrls: ['./notifications.component.css']
})
export class NotificationsComponent implements OnInit {
  notifications: NotificationEntry[];

  constructor(
    private route: ActivatedRoute,
    private modalService: ModalService,
    private messageBoxService: MessageBoxService,
    private notificationsService: NotificationsService
  ) {}

  ngOnInit() {
    this.route.data.subscribe(
      (data: { notifications: NotificationEntry[] }) => {
        this.notifications = data.notifications;
      }
    );
  }
}

Component.spe c

describe('NotificationsComponent', () => {
  let component: NotificationsComponent;
  let fixture: ComponentFixture<NotificationsComponent>;

  const registryVersionBasicData = new RegistryVersionBasicData(
    false,
    'versionId',
    new JsonDate('Unspecified', 631894104000000000),
    'user',
    'comment'
  )

  const notifications = new NotificationEntry(
    new JsonDate('Unspecified', 631894104000000000),
    'summary',
    'message',
    NotificationEntityType.StressScenario,
    'instance name',
    'instance key',
    registryVersionBasicData,
    'additional information')

  const notificationsArray = [notifications]

  beforeEach(() => {
    const activatedRouteStub = { data: of({ notifications: notificationsArray }) };
    const modalServiceStub = {};
    const messageBoxServiceStub = {};
    const notificationsServiceStub = {};

    TestBed.configureTestingModule({
      schemas: [NO_ERRORS_SCHEMA],
      declarations: [NotificationsComponent, OrderPipe, RenderDatePipe, VersionInfoPipe],
      providers: [
        { provide: ActivatedRoute, useValue: activatedRouteStub },
        { provide: ModalService, useValue: modalServiceStub },
        { provide: MessageBoxService, useValue: messageBoxServiceStub },
        { provide: NotificationsService, useValue: notificationsServiceStub },
      ]
    }).compileComponents();

    fixture = TestBed.createComponent(NotificationsComponent);
    component = fixture.componentInstance;
  });

  it('can load instance', () => {
    expect(component).toBeTruthy();
  });

  describe('ngOnInit', () => {
    it('should get notifications entry', () => {
      const activatedRouteStub = TestBed.get(ActivatedRoute);
      spyOnProperty(activatedRouteStub, 'data')

      component.ngOnInit();

      expect(component.notifications).toEqual(notificationsArray)
    });
  });
});

Ответы [ 2 ]

1 голос
/ 18 февраля 2020
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { NotificationsComponent } from './notifications.component';
import { ActivatedRoute } from '@angular/router';
import { ModalService, MessageBoxService, NotificationsService, NotificationEntry, JsonDate, NotificationEntityType, RegistryVersionBasicData } from 'src/app/shared';
import { OrderPipe } from 'ngx-order-pipe';
import { RenderDatePipe } from 'src/app/shared/pipes/renderdate.pipe';
import { VersionInfoPipe } from 'src/app/shared/pipes/versioninfo.pipe';
import { of } from 'rxjs';

fdescribe('NotificationsComponent', () => {
  let component: NotificationsComponent;
  let fixture: ComponentFixture<NotificationsComponent>;

  const registryVersionBasicData = new RegistryVersionBasicData(
    false,
    'versionId',
    new JsonDate('Unspecified', 631894104000000000),
    'user',
    'comment'
  );

  const notifications = new NotificationEntry(
    new JsonDate('Unspecified', 631894104000000000),
    'summary',
    'message',
    NotificationEntityType.StressScenario,
    'instance name',
    'instance key',
    registryVersionBasicData,
    'additional information');


  const route = { data: of({ notifications: [notifications] }) };


  beforeEach(() => {
    const modalServiceStub = {};
    const messageBoxServiceStub = {};
    const notificationsServiceStub = {};

    TestBed.configureTestingModule({
      schemas: [NO_ERRORS_SCHEMA],
      declarations: [NotificationsComponent, OrderPipe, RenderDatePipe, VersionInfoPipe],
      providers: [
        { provide: ActivatedRoute, useValue: route },
        { provide: ModalService, useValue: modalServiceStub },
        { provide: MessageBoxService, useValue: messageBoxServiceStub },
        { provide: NotificationsService, useValue: notificationsServiceStub },
      ]
    });

    fixture = TestBed.createComponent(NotificationsComponent);
    component = fixture.componentInstance;
  });

  it('can load instance', () => {
    expect(component).toBeTruthy();
  });

  describe('ngOnInit', () => {
    it('should get notifications entry', () => {
      component.ngOnInit();
      expect(component.notifications).toEqual([notifications]);
    });
  });
});

Самое простое из возможных решений. Используйте:

const route = { data: of({ notifications: [notifications] }) };

.., а затем используйте это значение в поставщиках компонентов:

{ provide: ActivatedRoute, useValue: route }

.. в качестве примитивного макета для ActivatedRoute. Тогда ваш контрольный пример может выглядеть следующим образом (TestBed не требуется):

  describe('ngOnInit', () => {
    it('should get notifications entry', () => {
      component.ngOnInit();
      expect(component.notifications).toEqual([notifications]);
    });
  });
0 голосов
/ 18 февраля 2020

Определите ваш activRouteStub следующим образом -

class ActivatedRouteStub {
    private _data = new BehaviorSubject(notifications);
    get data() {
        return this._data;
    }
    set data(notifications: NotificationEntry[]) {
        this.data.next(notifications)
    }
}

Затем используйте его в своих провайдерах как

{ provide: ActivatedRoute, useValue: new ActivatedRouteStub()}

Теперь вы можете изменить данные, выполнив

const activeRoute = testBed.get(ActivatedRoute);
activeRoute.data = [new Notification()];
...