Как издеваться над ControlContainer в угловом модульном тесте?

Как я могу смоделировать экземпляр ControlContainer, чтобы протестировать свой компонент?

У меня есть дочерний компонент, который вставляет ControlContainer в конструктор, поэтому его использование

<acr-score-card formGroupName="score"></acr-score-card>

а сам компонент

@Component({
  selector: 'acr-score-card',
  templateUrl: './score-card.component.html',
  styleUrls: ['./score-card.component.scss']
})
export class ScoreCardComponent implements OnInit {

  ...

  form: FormGroup;

  constructor(private ngControl: ControlContainer) { }

  ngOnInit() {
    this.form = <FormGroup>this.ngControl.control;
  }

  ...

}

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

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

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [TestingModule],
      declarations: [ScoreCardComponent],
      providers: [/** what goes here to mock the ControlContainer */]
      schemas: [NO_ERRORS_SCHEMA]
    })
      .compileComponents();
  }));

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

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});

Итак, повторяя вопрос, как я могу имитировать экземпляр ControlContainer, чтобы я мог протестировать свой компонент?


person Neil Stevens    schedule 10.01.2019    source источник
comment
Можете ли вы проверить эту ссылку? Он показывает способ внедрения COntrolContainers. Но поскольку ControlContainer - это интерфейс, вам нужно создать экземпляр с классами, реализующими интерфейс, например FormGroupDirective и т. Д.   -  person KiraAG    schedule 10.01.2019


Ответы (2)


Спасибо @KiraAG за комментарий и смог выяснить, что требуется по предоставленной ссылке, поэтому разместите здесь ответ на случай, если кто-то еще столкнется с этим вопросом.

Итак, в вашем тесте вам нужно provide экземпляр ControlContainer в вашем тестовом модуле, в основном это будет либо FormGroupDirective, либо FormControlDirective в зависимости от того, что вы ожидаете передать вашему компоненту.

Например, в вашем тестовом файле создайте FormGroup, который представляет часть формы, которую вы используете.

const fg: FormGroup = new FormGroup({
  'answer': new FormControl(''),
  ...
});

Затем создайте FormGroupDirective и установите для свойства form значение FormGroup, созданное выше.

const fgd: FormGroupDirective = new FormGroupDirective([], []);
fgd.form = fg;

Теперь в настройке тестового модуля вы можете указать ControlContainer

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [TestingModule],
      declarations: [ScoreCardComponent],
      providers: [
        { provide: ControlContainer, useValue: fgd }
      ]
      schemas: [NO_ERRORS_SCHEMA]
    })
      .compileComponents();
  }));

И все, инъекция конструктора довольна.

person Neil Stevens    schedule 14.01.2019
comment
Я следил за этим, но получаю сообщение об ошибке: нет поставщика для FormGroupDirective! - person HelloWorld; 03.12.2019
comment
Я получаю следующую ошибку: «Не могу найти элемент управления с неопределенным атрибутом имени any»? - person Rebecca Douglas; 12.02.2021
comment
Я унаследовал этот код ... this.scheduleFormGroup = this.controlContainer.control.get ('schedule'); ... поэтому мне пришлось обернуть его вот так ... const schedule: FormGroup = new FormGroup ({schedule: new FormGroup ({minute: new FormControl ('/ 5'), hour: new FormControl ('< / i> '), дата: новый FormControl (' '), месяц: новый FormControl (' '), день: новый FormControl (' * '), активный: новый FormControl (false)}) }); - person danday74; 17.03.2021

Я использовал ответ Нила Стивенса.

Но у меня было

viewProviders: [{provide: ControlContainer, useExisting: FormGroupDirective}],

в компоненте.

Поэтому в тестах я должен использовать

providers: [{provide: FormGroupDirective, useValue: fgd}],

Может, это кому-то поможет.

person Ruslan Svirski    schedule 25.02.2020
comment
Так было со мной! Спасибо!!! - person Mike Young; 17.12.2020