Изменение значения ложного объекта ввода после его инициализации в beforeEach () - PullRequest
0 голосов
/ 16 апреля 2020

Я работаю над тестированием компонента, child.component.ts . Компонент имеет простое условное выражение, которое выводит статус на основе значений объекта. Объект передается через Input() компоненту из родительского компонента. Я создал фиктивный объект в beforeEach() теста и пытаюсь изменить этот объект во втором операторе it(), чтобы два свойства имели разные значения.

Это упрощенное приложение для демонстрации того, что я пытаюсь сделать. Фундаментальная логика c в фактической логике в точности соответствует той, которую я предоставляю для кода ниже, однако объект, который я должен смоделировать в реальном модульном тесте, экспоненциально больше и представляет собой интерфейс тип, так что все свойства должны присутствовать - отсюда и желание сохранить его в пределах beforeEach(). Части этой логики c распределяются между несколькими различными тестами, поэтому, если возможно просто изменить значение объекта в одном месте, где я пытаюсь это сделать, это было бы идеально ... в противном случае это добавило бы еще 40+ строк моего кода.

Child.component.spe c .ts:

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

    // Set up the fake dataItem objet
    component.dataItem = {
      documentCount: 3,
      invoiceCount: 4
    };

    fixture.detectChanges();
  });

  // Works as expected
  it('should have a status of 1 if there are documents or invoices', () => {
    expect(fixture.componentInstance.status).toBe(1);
  });

  // Setting the documentCount and invoiceCount here doesn't seem to work
  it('should have a status of 0 if there are no documents or invoices', () => {
    component.dataItem.documentCount = 0;
    component.dataItem.invoiceCount = 0;
    fixture.detectChanges();
    expect(fixture.componentInstance.status).toBe(0);
  });

App.component.ts:

export class AppComponent {
  dataItem = {
    documentCount: 3,
    invoiceCount: 4
  };
}

App.component. html:

<app-child [dataItem]="dataItem"></app-child>

Child.component.ts:

export class ChildComponent implements OnInit {

  @Input() dataItem;

  status: number;

  ngOnInit(): void {
    if (this.dataItem.documentCount === 0 && this.dataItem.invoiceCount === 0) {
      this.status = 0;
    } else {
      this.status = 1;
    }
  }

}

Child.component. html:

<p>{{ this.status }}</p>

1 Ответ

0 голосов
/ 17 апреля 2020

Причина, по которой component.dataItem.documentCount = 0; и component.dataItem.invoiceCount = 0; не работают, может заключаться в том, что этот объект является ссылочным типом, а изменение свойства ссылочного типа не приводит к обнаружению изменений ИЛИ, скорее всего, потому что ngOnInit является больше не запускается.

Структурируйте свои тесты так:

let stockDataItem = {
      documentCount: 3,
      invoiceCount: 4
};

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

  describe('stock dataItem', () => {
     beforeEach(() => {
       // set dataItem
       component.dataItem = stockDataItem;
       // this fixture.detectChanges() will call ngOnInit. 
       // the first fixture.detectChanges() calls ngOnInit after createComponent
       fixture.detectChanges();
     });
    // Works as expected
    it('should have a status of 1 if there are documents or invoices', () => {
      expect(component.status).toBe(1);
    });
  });

  describe('0 invoice count and 0 document count', () => {
     beforeEach(() => {
       // set dataItem
       component.dataItem = {...stockDataItem, invoiceCount: 0, documentCount: 0};
       fixture.detectChanges();
     });

   // Setting the documentCount and invoiceCount here doesn't seem to work
   it('should have a status of 0 if there are no documents or invoices', () => {
     expect(component.status).toBe(0);
   });
  });
...