Невозможно пройти тест Jest, чтобы пройти в Angular - PullRequest
0 голосов
/ 10 января 2019

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

Я пытаюсь использовать шутки Jest, но хотя я уже перечитал документацию десятки раз, я все еще не уверен, что делаю это правильно. Иногда мне нужен шпион, а иногда я просто хочу, чтобы смоделированная функция (обычно служебная функция) возвращала некоторые фиктивные данные. Я чувствую, что просто не понимаю какую-то магию насмешки над Шутом.

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

РЕДАКТИРОВАТЬ: макет всей службы Кажется, что это работает лучше, поскольку мои тестовые утверждения проходят, но тест все еще не выполняется из-за ошибки в стороннем модуле. Я пытался добавить NO_ERRORS_SCHEMA, но это не помогает:

TypeError: bA.getPropertyValue is not a function
      at R (node_modules/jqwidgets-scripts/jqwidgets/jqxcore.js:14:36743)

Компонент ngOnInit ()

ngOnInit() {
    this._dataService.getData().subscribe(
      data => {
        this.populate(data); // <--this line appears not to be running, as this function populates this.source.localdata with this data
        this.dataAdapter = new jqx.dataAdapter(this.source);
      },
      error => {
        console.error(error);
      }
    );
  }

Мой тест

import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { jqxGridComponent } from 'jqwidgets-scripts/jqwidgets-ts/angular_jqxgrid';
import { ProgressComponent } from './progress.component';
import { ProgressGridDataService } from './progress.service';
import { WorkingFileService } from 'src/app/services/working-file/working-file.service';
import { IProgressData } from './progress.interfaces';
import { of } from 'rxjs';

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

  class ProgressServiceSpy {
    testHistory: IProgressData = {
      recordId: 1,
      product: 'A',
    };
    getData = jest.fn().mockImplementation(() => of(Object.assign({}, this.testHistory)));

    restartLoad = jest.fn();
  }
  beforeEach(
    async(() => {
      TestBed.configureTestingModule({
        declarations: [ProgressComponent, jqxGridComponent],
        providers: [
          WorkingFileService,
          { provide: ProgressGridDataService, useValue: {} },
        ],
      })
      .overrideComponent(ProgressComponent, {
        set: {
          providers: [
            { provide: ProgressGridDataService, useClass: ProgressServiceSpy },
          ],
        },
      })
      .compileComponents();
      fixture = TestBed.createComponent(ProgressComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
    })
  );

  describe('retry button', () => {
    it('should call the restartLoad service and pass a record ID', () => {
      component.ngOnInit();
     expect(component.source).toHaveProperty('localdata');
      expect(component.source.localdata).toEqual(testHistory);
    });
  });
});

Ответы [ 2 ]

0 голосов
/ 10 января 2019

Мне удалось разобраться с дальнейшими раскопками. Я последовал примеру приложения Angular Stackblitz Hero и полностью издевался над всем моим сервисом, так как он на самом деле не тестировался. Я не понимаю, почему для установки шпионского сервиса нужно использовать overrideComponent вместо того, чтобы просто делать это в конфигурации TestBed, но я думаю, это потому, что мой компонент имеет сервис в своем собственном массиве providers ( docs *) 1006 *).

Что касается странной bA.getPropertyValue is not a function ошибки, эта проблема Github поставила меня на правильный путь, чтобы я смог добавить этот фрагмент к jestGlobalMocks.ts, и, наконец, мой тест прошел!

Хотелось бы, чтобы я лучше знал, что я делаю с тестированием в Angular с Jest, потому что потратить целых 8 часов только на то, чтобы запустить и сдать этот крошечный тест, является той самой причиной, по которой моему приложению так не хватает покрытия тестов.

Object.defineProperty(window, 'getComputedStyle', {
  value: () => ({
    getPropertyValue: prop => {
      return '';
    },
  }),
})
0 голосов
/ 10 января 2019

Вы должны получить ссылку на сервис из TestBed, а затем смоделировать или SpyOn:

    import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { jqxGridComponent } from 'jqwidgets-scripts/jqwidgets-ts/angular_jqxgrid';
import { ProgressComponent } from './progress.component';
import { ProgressGridDataService } from './progress.service';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { HttpClient } from '@angular/common/http';
import { IProgressData } from './progress.interfaces';
import { of } from 'rxjs';

describe('ProgressComponent', () => {
  let component: ProgressComponent;
  let progressService: ProgressGridDataService;
  let fixture: ComponentFixture<ProgressComponent>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [ProgressComponent, jqxGridComponent],
      imports: [HttpClientTestingModule],
      providers: [ProgressGridDataService, WorkingFileService],
    });
    fixture = TestBed.createComponent(ProgressComponent);
    component = fixture.componentInstance;
    progressService = TestBed.get(ProgressGridDataService); // Here get the service
    fixture.detectChanges();
  });

  describe('component load', () => {
    let testHistory: IProgressData;

    beforeEach(() => {
      testHistory = {
        recordId: 1,
        product: 'A',
        fileId: 'A',     
      };
    });
    it('should pull the data from the service into a component property', () => {
     //I'm trying to use a Jest mock function, but I'm not sure I'm using it right 

  //Mock and Spy now....

      jest.spyOn(progressService, 'getData').mockImplementation(() => of(testHistory));
      component.ngOnInit();

      expect(component.source).toHaveProperty('localdata');
      expect(component.source.localdata).toEqual(testHistory)
      //would love to have an expectation that the service was called properly, but not sure how to do Jest spies on that function correctly.
       });
      });
    });
...