TypeError: Невозможно прочитать свойство 'subscribe' из неопределенного, используя spyOn - PullRequest
1 голос
/ 11 февраля 2020

Я ожидаю, что массив будет неопределенным в тесте моего приложения Angular. Для этого мой тест должен сначала вызвать функцию моего тестируемого компонента. Внутри этой функции он подписывается на функцию сервиса.

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

let service: Service;
const mockService = new MockService();
mockService.getById = of([]);

beforeEach(async(() => {
    return TestBed.configureTestingModule({
      declarations: [leaving out for now],
      imports: [leaving out for now],
      providers: [
        {
          provide: Service,
          useValue: mockService 
        }
      ]
    })
      .compileComponents();
  }));

beforeEach(() => {
    fixture = TestBed.createComponent(Component);
    component = fixture.componentInstance;

    service = fixture.debugElement.injector.get(Service);

    fixture.detectChanges();
  });

describe('describe test', function () {
    it('test', function () {
      //spyOn(mockService, 'getItemsById');
      //spyOn(mockService, 'getItemsById').and.returnValue(of('nothing'));
      //spyOn(service, 'getItemsById');
      //spyOn(mockService, 'getItemsById').and.callThrough();
      //spyOn(service, 'getItemsById').and.callThrough();
      //spyOn(service, 'getItemsById').and.returnValue(of('nothing')); syntax error
      //spyOn(service, 'getItemsById').and.returnValue({ subscribe: () => {} }); syntax error
      //spyOn(mockService, 'getItemsById').and.returnValue({ subscribe: () => {} }); syntax error
      component.getList();

      expect(component.array).toBeUndefined();
    });
  });

Все, что я пытался сделать, все еще приводит к ошибке:

TypeError: Невозможно прочитать свойство 'subscribe' из неопределенного

и ссылается на строку в функции моего компонента, где я подписываюсь на функцию getItemsById службы

мой фиктивный сервис:

getById: Observable<any>;

constructor() {}

getItemsById(id: number){
    return this.getById;
  }

мой протестированный компонент, который подписывается на функцию исходного сервиса:

getList(): Model[]{
    let temp: Model[] = [];
    for (let item of this.items){
      let id = item.id;
      this.service.getItemsById(id).subscribe(
        singleIdItem => {
          temp= temp.concat(singleIdItem);
        }
      );
    }
    return temp;
  }

Я не включил свой исходный сервис, так как он проверяется, пожалуйста, дайте мне знать, если это необходимо. Я предполагаю, что решение - это некая форма spyOn, но я перепробовал все, что смог найти.

Использование Angular 8

Ответы [ 2 ]

1 голос
/ 11 февраля 2020

Попробуйте это прямо перед тем, как первый beforeEach:

let service: Service;
const mockService = new MockService();
mockService.getById = of([]);

Я думаю добавить mockService.getById = of([]); во второй beforeEach (удалите его отсюда, теперь, когда он добавлен вверху) слишком поздно (услуга без getById уже была введена в поставщиках configureTestingModule).

==================== == Редактировать ===================

Я бы использовал createSpyObj примерно так:

let mockService: any;

beforeEach(async(() => {
      // can name service (first argument) to anything you want, but I called in service in this scenario. It is internal for you
    mockService = jasmine.createSpyObj('service', ['getItemsById']);
    TestBed.configureTestingModule({
      declarations: [leaving out for now],
      imports: [leaving out for now],
      providers: [
        {
          provide: Service,
          useValue: mockService 
        }
      ]
    })
      .compileComponents();
  }));

beforeEach(() => {
    fixture = TestBed.createComponent(Component);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

it('should do something', () => {
   mockService.getItemsById.and.returnValue(of([]));
   component.getList();
   // the rest of your assertions.
});
0 голосов
/ 12 февраля 2020

В моем тесте мне нужно было вернуть правильное значение из моего сервиса

describe('describe test', function () {
    it('test', function () {
      spyOn(service, 'getItemsById').and.returnValue(of([{name: 'name', id: 10, otherId: 12, startTime: 'time', endTime: 'time', description: 'desc', insertTime: 'time', insertUser:'user', updateTime: 'time', updateUser: 'user'}]));

      component.getList();

      expect(component.array.size).toEqual(1);
    });
  });

Возвращенное значение имеет тип Model[], как определено в моей функции getList в моем сервисе.

...