How to test Angular's resource() / rxResource()?

Discussão em 'Angular' iniciado por fservantdev, Abril 7, 2025.

  1. fservantdev

    fservantdev Guest

    I am trying to unittest a service which uses the new rxResource utility, introduced in Angular 19:

    import { computed, inject, Injectable, signal } from '@angular/core';
    import { rxResource } from '@angular/core/rxjs-interop';
    import { Observable, of } from 'rxjs';
    import { RESULTS_REPOSITORY } from '../some-tokens';

    @Injectable()
    export class CommonResultsDataStore {
    readonly query = signal<string | null>(null);

    private readonly repositoryService = inject<{ search: (v: string) => Observable<object[]>; }>(RESULTS_REPOSITORY);
    private readonly resource = rxResource({
    request: () => this.query(),
    loader: ({ request }) => request ? this.repositoryService.search(request) : of(null),
    });

    data = computed(() => this.resource.value() ?? []);
    }


    Here is my test suite (written in Jest):

    import { TestBed } from '@angular/core/testing';
    import { Subject } from 'rxjs';
    import { RESULTS_REPOSITORY } from '../some-tokens';

    import { CommonResultsDataStore } from '.';

    describe('CommonResultsDataStore', () => {
    const searchSubject = new Subject<object[]>();
    const mockRepository = {
    search: jest.fn((_v: string) => searchSubject.asObservable()),
    };

    let service: CommonResultsDataStore;

    beforeEach(() => {
    TestBed.configureTestingModule({
    providers: [
    { provide: RESULTS_REPOSITORY, useValue: mockRepository },
    CommonResultsDataStore,
    ],
    });
    service = TestBed.inject(CommonResultsDataStore);
    });

    describe('initial state', () => {
    it('should return empty results', () => {
    expect(service.data()).toStrictEqual([]);
    expect(mockRepository.search).not.toHaveBeenCalled();
    });
    });

    describe('with remote query', () => {
    beforeEach(() => {
    service.query.set('toto');
    });

    it('should return empty results', () => {
    expect(service.data()).toStrictEqual([]);
    expect(mockRepository.search).toHaveBeenCalledTimes(1); // ❌ why does it not trigger any call?
    expect(mockRepository.search).toHaveBeenCalledWith('toto');
    });

    it('should return results', () => {
    // When
    const flushedData = [
    { id: 1 },
    { id: 2 },
    { id: 3 },
    { id: 4 },
    { id: 5 },
    ];
    searchSubject.next(flushedData);

    // Then
    expect(service.data()).toStrictEqual([]);
    expect(mockRepository.search).toHaveBeenCalledTimes(1); // ❌ why does it not trigger any call?
    expect(mockRepository.search).toHaveBeenCalledWith('toto');
    });
    });
    });


    My issue is that I was expecting my repository service to be called after setting the request signal, but nothing is trigger.
    Could you please explain me why?
    What is the recommanded way to test such services?

    I also tried going through observables with the toObservable utility in another service,
    and manually by subscribing to them in tests before setting the request signal value, but without success.

    Continue reading...

Compartilhe esta Página