Как провести модульное тестирование EntityCollectionServiceBase в @ ngrx / data? - PullRequest
3 голосов
/ 27 мая 2020

У меня есть фиктивный сервис:

export class PatientService extends EntityCollectionServiceBase<Patient> {
  constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
    super('Patient', serviceElementsFactory);
  }
}

У меня есть следующий тест:

describe('PatientService', () => {
  let service: PatientService;

  beforeEach(() => {
    TestBed.configureTestingModule({});
    service = TestBed.inject(PatientService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

И он дает мне:

NullInjectorError: No provider for EntityCollectionServiceElementsFactory

Итак, я обновился следующим образом:

describe('PatientService', () => {
  let service: PatientService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [EntityDataModuleWithoutEffects.forRoot(entityConfig)],
      providers: [provideMockStore()],
    });
    service = TestBed.inject(PatientService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

Но теперь он дает мне:

NullInjectorError: No provider for ScannedActionsSubject!

Как я могу правильно исправить свой тест?

Ответы [ 2 ]

1 голос
/ 01 июня 2020

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

В нашем случае это означает, что PatientService должен быть предоставлен как тестовый модуль, а EntityCollectionServiceElementsFactory должен быть предоставлен как его зависимость.

Но EntityCollectionServiceElementsFactory имеет собственные зависимости: EntityDispatcherFactory, EntityDefinitionService, EntitySelectorsFactory и EntitySelectors$Factory. Что мы не хотим предоставлять, потому что у них могут быть собственные зависимости, ухудшающие нашу жизнь.

Чтобы исправить это, давайте просто заменим EntityCollectionServiceElementsFactory.

describe('PatientService', () => {
  let service: PatientService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        PatientService,
        {
          provide: EntityCollectionServiceElementsFactory,
          // our stub
          useValue: {
            methodsToFake: jasmine.createSpy(),
            // ....
          },
        },
      ],
    });
    service = TestBed.inject(PatientService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});

Также, чтобы избежать боли имитирующие зависимости и его методы в будущем вы можете использовать ng-mocks . Тогда тест мог бы выглядеть так:

describe('PatientService', () => {
  let service: PatientService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        PatientService,
        {
          provide: EntityCollectionServiceElementsFactory,
          useValue: MockService(EntityCollectionServiceElementsFactory),
        },
      ],
    });
    service = TestBed.inject(PatientService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });
});
0 голосов
/ 28 мая 2020

Вам нужно будет настроить весь модуль данных, как в «обычном Angular модуле».

Это означает предоставление хранилища, эффектов и объекта данных.

Может быть способ получше, но ... не знаю ?‍♂️

...