Angular testing http API call fails. Error: Expected one matching request for criteria "Match...

Discussão em 'Angular' iniciado por Saeid Khodarahmi, Março 8, 2025.

  1. http API service .ts file:


    @Injectable({
    providedIn: 'root',
    })
    export class AppAPIService {
    datePipe = inject(DatePipe);
    toastService = inject(ToastrService);
    appSignalState = inject(AppSignalState);
    router = inject(Router);

    // devicePrint = inject(DevicePrintService);
    appNavigation = inject(UserNavigationService);
    httpClient = inject(HttpClient);
    spinner = inject(NgxSpinnerService);
    //signal
    private readonly apiBaseUrl = this.appSignalState.getApiBaseUrl;
    logout(): Observable<any> {
    this.spinner.show();
    return this.httpClient.post(this.apiBaseUrl() + 'logout', {}).pipe(
    take(1),
    timeout(this.apiTimeoutValue),
    finalize(() => {
    this.spinner.hide();
    this.appSignalState.performStateLogoutUpdate();
    this.router.navigate(['/login']);
    })
    );
    }
    }

    code for appSignal state


    @Injectable({
    providedIn: 'root',
    })
    export class AppSignalState {
    // ...
    getApiBaseUrl = computed<string | null | undefined>(() => {
    return this.state()?.general?.baseUrl;
    });
    }

    code for the test file:


    import { TestBed } from '@angular/core/testing';
    import {
    HttpTestingController,
    provideHttpClientTesting,
    } from '@angular/common/http/testing';
    import { AppAPIService } from './api.service';
    import { ToastrService } from 'ngx-toastr';
    import { NgxSpinnerService } from 'ngx-spinner';
    import { AppSignalState } from '../app-state/app-state.service';
    import { provideRouter, Router } from '@angular/router';
    import { DatePipe } from '@angular/common';
    import { provideHttpClient } from '@angular/common/http';
    import { linkedSignal, signal, WritableSignal } from '@angular/core';
    import { UserNavigationService } from './app-navigation.service';
    import { fakeAsync, tick } from '@angular/core/testing';

    describe('AppAPIService', () => {
    let httpMock: HttpTestingController;
    let toastrService: jasmine.SpyObj<ToastrService>;
    let spinnerService: jasmine.SpyObj<NgxSpinnerService>;
    let stateMock: jasmine.SpyObj<AppSignalState>;
    let service: AppAPIService;
    let appNavigation: jasmine.SpyObj<UserNavigationService>;
    let router: jasmine.SpyObj<Router>;

    beforeEach(() => {
    // spell-checker: disable
    const toastrServiceMock = jasmine.createSpyObj('ToastrService', [
    'error',
    'success',
    ]);
    // spell-checker: enable
    const spinnerServiceMock = jasmine.createSpyObj('NgxSpinnerService', [
    'show',
    'hide',
    ]);
    const mockAppState = jasmine.createSpyObj('AppSignalState', [], {
    getApiBaseUrl: signal('http://localhost:9091/'),
    userResetPasswordRequired: linkedSignal<boolean>(() => false),
    isContractAgreementRequired: linkedSignal<boolean>(() => false),
    isUserLoggedIn: linkedSignal<boolean>(() => false),
    updateLoginResponse: linkedSignal<any>(() => null),
    performStateLogoutUpdate: linkedSignal<any>(() => null),
    });
    const routerSpy = jasmine.createSpyObj('Router', ['navigate']);

    TestBed.configureTestingModule({
    imports: [],
    providers: [
    provideHttpClientTesting(),
    provideHttpClient(),
    provideRouter([]),
    { provide: UserNavigationService, useValue: {} },
    { provide: ToastrService, useValue: toastrServiceMock },
    { provide: NgxSpinnerService, useValue: spinnerServiceMock },
    { provide: Router, useValue: routerSpy },

    DatePipe,
    AppAPIService,

    {
    provide: AppSignalState,
    useValue: mockAppState,
    },
    ],
    });

    httpMock = TestBed.inject(HttpTestingController);
    toastrService = TestBed.inject(
    ToastrService
    ) as jasmine.SpyObj<ToastrService>;
    spinnerService = TestBed.inject(
    NgxSpinnerService
    ) as jasmine.SpyObj<NgxSpinnerService>;
    stateMock = TestBed.inject(
    AppSignalState
    ) as jasmine.SpyObj<AppSignalState>;
    service = TestBed.inject(AppAPIService);
    appNavigation = TestBed.inject(
    UserNavigationService
    ) as jasmine.SpyObj<UserNavigationService>;
    router = TestBed.inject(Router) as jasmine.SpyObj<Router>;
    });

    afterEach(() => {
    httpMock.verify();
    });

    it('should be created', () => {
    expect(service).toBeTruthy();
    });

    it('Should call Logout with success response', () => {
    const mockResponse = { success: true };

    // Call the logout method
    service.logout().subscribe((response) => {
    console.log(response);
    expect(response).toEqual(mockResponse);
    });

    // Ensure spinner is shown
    expect(spinnerService.show).toHaveBeenCalled();
    // Mock the HTTP request
    const req = httpMock.expectOne(stateMock.getApiBaseUrl() + 'logout');
    // const req = httpMock.expectOne(
    // (req) =>
    // req.method === 'POST' &&
    // req.url === stateMock.getApiBaseUrl() + 'logout'
    // );
    expect(req.request.method).toBe('POST');
    req.flush(mockResponse);

    // Ensure finalize actions are called
    expect(spinnerService.hide).toHaveBeenCalled();
    expect(stateMock.performStateLogoutUpdate).toHaveBeenCalled();
    expect(router.navigate).toHaveBeenCalledWith(['/login']);
    });


    });

    Error I am getting when I run: ✔ Browser application bundle generation complete. Chrome 133.0.0.0 (Windows 10) AppAPIService Should call Logout with success response FAILED Error: Expected one matching request for criteria "Match URL: http://localhost:9091/logout", found none. at HttpClientTestingBackend.expectOne (node_modules/@angular/common/fesm2022/http/testing.mjs:274:19) at UserContext.apply (src/app/services/api.service.spec.ts:105:26) at _ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:369:28) at ProxyZoneSpec.onInvoke (node_modules/zone.js/fesm2015/zone-testing.js:2082:39) at _ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:368:34) at ZoneImpl.run (node_modules/zone.js/fesm2015/zone.js:111:43) at runInTestZone (node_modules/zone.js/fesm2015/zone-testing.js:216:38) at UserContext. (node_modules/zone.js/fesm2015/zone-testing.js:234:32)

    Continue reading...

Compartilhe esta Página