serrgg
serrgg

Reputation: 65

How to simulate delay?

There is the service that contain state:

@Injectable({
  providedIn: 'root'
})
export class WordsService {

  words: string[] = [
    'qqq',
    'www',
    'eee',
    'rrr',
    'ttt',
    'yyy',
  ];

  constructor() { }

}

There is a button in a component. Service state is display in a template when user click by this button.

@Component({
  selector: 'app-page3',
  template: `
    <div *ngFor="let word of serviceWords" class="word-el">
        {{ word }}
    </div>
    <button (click)="getWordsFromService()" id="getWordsBtn">get words from service</button>
  `,
  styleUrls: ['./page3.component.scss']
})
export class Page3Component {
  serviceWords: string[] = [];
  constructor(private wordsService: WordsService) { }
  getWordsFromService() {
    this.serviceWords = this.wordsService.words;
  }
}

I try to simulate delay then check displaying service state in a template.

beforeEach(async () => {
  await TestBed.configureTestingModule({
    declarations: [ Page3Component ]
  })
  .compileComponents();
});

it('should display list after getWords-button', () => {
  fixture.detectChanges();
  const compliedComponent = fixture.debugElement.nativeElement;

  const btn = compliedComponent.querySelector('#getWordsBtn');
  btn.dispatchEvent(new Event('click'));

  setTimeout(() => {
    expect(compliedComponent.querySelector('.word-el')).toBeTruthy();  
  }, 1000);
});

Unfortunatelly this unit test is not working. I get follow message: spec has not expectations

Please help me simulate delay after buttons click.

I try to use tick() and waits() but they were not working.

Upvotes: 1

Views: 438

Answers (1)

Ilia Komarov
Ilia Komarov

Reputation: 633

  1. In situations like these you should use done-arg in test like:
it('should display list after getWords-button', (done: DoneFn) => {
  fixture.detectChanges();
  const compliedComponent = fixture.debugElement.nativeElement;

  const btn = compliedComponent.querySelector('#getWordsBtn');
  btn.dispatchEvent(new Event('click'));

  setTimeout(() => {
    expect(compliedComponent.querySelector('.word-el')).toBeTruthy();
    done();
  }, 1000);
});
  1. I think correct way of change check is to detect fixture changes:
it('should display list after getWords-button', () => {
  fixture.detectChanges();
  const compliedComponent = fixture.debugElement.nativeElement;

  const btn = compliedComponent.querySelector('#getWordsBtn');
  btn.dispatchEvent(new Event('click'));
  fixture.detectChanges();

  expect(compliedComponent.querySelector('.word-el')).toBeTruthy();  
});

Upvotes: 2

Related Questions