how can I test a component that have a function that use async await?

162 Views Asked by At

I have a problem. I have a function that use a async await to get data, but in the moment that I try test it. I don't know how to do that. I tried this this is my component

async loadTodos() {
    try {
      const todosData = await this.testService.loadTodos();
      this.todos = todosData;
      console.log('posts', todosData);
    } catch (error) {
      console.log(error);
    }
  }

this is my service file

export class TestService {
  constructor(private readonly http: HttpClient) {}
  async loadTodos(): Promise<any[]> {
    return this.http
      .get<any[]>('https://jsonplaceholder.typicode.com/todos')
      .toPromise();
  }
}

and finally this is my test

it('test', () => {
    const response2 = [
      {
        userId: 1,
        id: 1,
        title: 'delectus aut autem',
        completed: false,
      },
      {
        userId: 1,
        id: 2,
        title: 'quis ut nam facilis et officia qui',
        completed: false,
      },
    ];
    testServiceSpy.loadTodos.and.returnValue(of(response2).toPromise());
    component.loadTodos();

    expect(component.todos).toEqual(response2);
  });

I don't have error in the sintax, but in the terminal I see this.

 TypeError: Cannot read properties of undefined (reading 'loadTodos')
1

There are 1 best solutions below

0
Wesley Trantham On

This indicates that testServiceSpy is null. What you can do is check that you're setting it in the beforeEach or do something like this. You will also need to make your test itself async and await the call to the component.

it('test', async () => {  
  // grab the instance of the TestService
  const serviceSpy = TestBed.inject(TestService) as jasmine.SpyObj<TestService>;
  const response2 = [
  {
    userId: 1,
    id: 1,
    title: 'delectus aut autem',
    completed: false,
  },
  {
    userId: 1,
    id: 2,
    title: 'quis ut nam facilis et officia qui',
    completed: false,
  },
  ];
  serviceSpy.loadTodos.and.returnValue(of(response2).toPromise());
  // await the call to the component
  await component.loadTodos();

  expect(component.todos).toEqual(response2);
});