angular.io/api/core/InjectionToken

я есть компонент, который я пытаюсь настроить и протестировать с помощью TestBed.

Этот компонент содержит один класс, имеющий параметр в конструкторе, который является интерфейсом, а не конкретным классом. Этот интерфейс удовлетворяется тем классом, который я выберу (реальный или mok для модульного тестирования). Но когда я создаю компонент, который использует этот сервис в TestBed, я не могу понять, как определить этот параметр для конфигурации TestBed.

Вот конфигурация TestBed для компонента:

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ PanelContentAreaComponent
          ],
      providers:[
        MenuCommandService, ProcedureDataService, IOpenService],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
    .compileComponents();
  }));

Служба, которая испытывает затруднения при построении в TestBed, представляет собой ПроцедураDataService. Это определение ниже:

@Injectable()
export class ProcedureDataService {

serverOpenFile: OpenFile;

constructor(private _openService: IOpenService) {
    this.serverOpenFile = emptyFileStatus;
}

Один параметр в конструктореProcedureDataService являетсяIOpenService чье определение:

export interface IOpenService {
    openFile(fileType: string, dataType: string, filePath: string) ;
}

Как видите, это интерфейс, а не конкретный класс.

В моем тесте модуля обслуживания мы смоделировали IOpenService, реализовав его следующим образом:

export class mockOpenService implements IOpenService{

    constructor(){}

    openFile(fileType: string, dataType: string, filePath: string) {
        let fileContent: OpenFile;
... 
...
[fake the data with mok junk]
...
        fileContent = {
            'filePath': filePath,
            'fileName': name,
            'openSuccess': isSuccess,
            'error': errorMsg,
            'fileData': jsonData
        };

        return Observable.of(fileContent);

    }

}

Это прекрасно работает в тестовом модуле ServiceProDataService. И, конечно же, в реальном коде мы реализуем IOpenService с полностью реализованной службой открытия файлов, которая правильно получает данные.

Но при попытке использовать этот сервис внутри компонента я получаю следующую ошибку:

PanelContentAreaComponent should create FAILED
        Failed: IOpenService is not defined
        ReferenceError: IOpenService is not defined

Это имеет смысл, поэтому я пытаюсь выяснить, как сказать TestBed, что у меня есть конкретная реализация класса этого IOpenService, которую я хочу использовать. Я пытался это, но это не удается:

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ PanelContentAreaComponent
          ],
      providers:[
        {provide: IOpenService, useClass: mockOpenService},
        MenuCommandService, ProcedureDataService, IOpenService],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
    .compileComponents();
  }));

Компилятор говорит мне:

(31,19): error TS2693: 'IOpenService' only refers to a type, but is being used as a value here.

и я все еще получаю:

PanelContentAreaComponent should create FAILED
        Failed: IOpenService is not defined
        ReferenceError: IOpenService is not defined

Итак, как мне инструктироватьTestBed что у меня есть определенный класс (mockOpenService) реализация параметра интерфейса (IOpenService) необходим для обслуживания (ProcedureDataService) предоставляется для тестирования этого компонента (PanelContentAreaComponent)?

Ответы на вопрос(1)

Ваш ответ на вопрос