Home > OS >  Angular Unit Testing: Observable not returning results
Angular Unit Testing: Observable not returning results

Time:03-03

I'm working on an old Angular app and trying to unit test that the functions work as expected.

I'm simply trying to test that a function returns the correct http request but the test isn't able to read the observable.

import {HttpClient} from '@angular/common/http';

@Injectable()
export class MyService {
  constructor(private http: HttpClient) {}

  getUrl() {
     //lots of logic to determine which url to get

     return this.http.put(url, null, { headers: requestHeaders, withCredentials: true 
     }).pipe(
      map((response: any) => {
        return response;
     }));
  }

}

Is there a way to test the result of this getUrl function?

If I simply log the result of this function, I get an observable.

Observable{_isScalar: false, source: Observable{_isScalar: false, source: Observable{_isScalar: ..., source: ..., operator: ...}, operator: MapOperator{project: ..., thisArg: ...}}, operator: CatchOperator{selector: handleError(error) { ... }, caught: Observable{_isScalar: ..., source: ..., operator: ...}}}

And If I subscribe to this observable, nothing happens.

let test = null;
service.getUrl().subscribe((value) => {
  test = value
});

console.log('test result', test);

This will log null.

Would appreciate any advice on how I can get the result of this function. thanks

CodePudding user response:

There are several approaches to unit testing services in Angular. You can read about it here: Testing HTTP Services

Another approach is to create a mock service in your *.spec.ts file.

const MOCK_GET_URL_RESPONSE = 'test';

export class MockService() {
    // Implement service functions here
    getUrl(): Observable<any> {
        return of(MOCK_GET_URL_RESPONSE);
    }
}

describe('ABCComponent', () => {
    let component: ABCComponent;
    let fixture: ComponentFixture<ABCComponent>;
    let service: MockService;

    beforeEach(async () => {
        await TestBed.configureTestingModule({
            declarations: [ABCComponent],
            imports: [CommonModule, HttpClientTestingModule],
            // Provide your service and indicate which
            // class is to be used to mock it
            providers: [{ provide: MyService, useClass: MockService }],
        }).compileComponents();
    });

    it('should create', () => {
        service.getUrl().subscribe((res) => {
            console.log(res); // test
            expect(res).not.toBeNull(); // true
        });
    });
});

If you choose to test using mock services and in general, it is best practice to define the data type of response. So map your API responses to a type instead of any.

  • Related