How to unit-test an Angular v19 `resource` and trigger the evaluation of input-signal changes?

Discussão em 'Angular' iniciado por hgoebl, Fevereiro 3, 2025.

  1. hgoebl

    hgoebl Guest

    I have a Service which contains a resource (for a list of country-objects). Unit-testing the usual way seems not to work, even with fakeAsync and tick. Changes on the Subject which feeds the request-input do not trigger the loader.

    export class CountryService {
    private http = inject(HttpClient);
    private translocoService = inject(TranslocoService);
    private language = toSignal(this.translocoService.langChanges$);

    public readonly countryListResource = resource({
    request: this.language,
    loader: (params) => {
    const language = params.request;
    return lastValueFrom(this.fetchCountries(language));
    },
    }).asReadonly();

    public constructor() {
    effect(() => console.log("CountryService: language changed to", this.language()));
    this.translocoService.langChanges$.subscribe((lang) =>
    console.log("translocoService.langChanges$ changed: " + lang),
    );
    }

    private fetchCountries(language: string): Observable<Country[]> {
    return this.http
    .get<Country[]>(`assets/countries/countries-${language}.json`);
    }
    }


    This is the unit-test:

    describe("CountryService", () => {
    let service: CountryService;
    let httpMock: HttpTestingController;
    let languageSubject = new Subject<string>();

    beforeEach(() => {
    TestBed.configureTestingModule({
    providers: [
    provideHttpClient(),
    provideHttpClientTesting(),
    { provide: TranslocoService, useValue: { langChanges$: languageSubject } },
    ],
    });

    service = TestBed.inject(CountryService);
    httpMock = TestBed.inject(HttpTestingController);
    });

    it("should retrieve a list of countries from assets", fakeAsync(() => {
    const expectedEmpty = service.countryListResource.value();
    expect(expectedEmpty).toBeUndefined();

    // act
    languageSubject.next("en");
    tick();

    // assert [1]
    const req = httpMock.expectOne("assets/countries/countries-en.json");

    // act
    req.flush(mockCountries); // Simulates backend response
    tick();

    // assert [2]
    expect(service.countryListResource.value()).toEqual(mockCountries);
    }));
    });


    The test fails with (see assert [1]):


    Error: Expected one matching request for criteria "Match URL: assets/countries/countries-en.json", found none.
    ​

    In the output on the console, the subscription of the langChanges$ outputs, but the effect doesn't output anything.

    Is there a way to trigger the evaluation of the resource request Signal?

    BTW the service works without problems in production, only the unit-test causes me headaches.

    Continue reading...

Compartilhe esta Página