15

I have checked a lot of articles and answers but I don't seem to find the right way to mock HTTP Requests for my methods. I want to test my frontend application independently from the backend. Here is the type of methods I have:

 private getProfile() {
    this.http
      .get('go/profile/get', {withCredentials: true})
      .subscribe((profile: Profile) => {
        this.user.profile = profile;
        this.updateLineMsgs();
      });
  }

Any suggestions ?

6 Answers 6

9

You can always create a mock method by your own and mock the response that you expect from the backend. In your example it could be

 public static mockGetProfile(){
    const response = JSON.parse(`
     "name": "abc",
     "active": true,
     ...all other json fields that you want
     `);

    let obs = new Observable((subscriber) => {
        setTimeout(()=>{
            subscriber.next(response);
            subscriber.complete();
        }, 3000);
    });
    return obs;
}

The above observable will complete after 3 seconds or what ever period you define, simulating in a way the response from a backend server which will need some time to be available.

Sign up to request clarification or add additional context in comments.

Comments

9

Usually i mock my Http requests with HttpClientTestingModule :

import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

export class TestService {
    constructor(private http: HttpClient) {}
}

describe('AppInterceptor', () => {
    let service: TestService;
    let httpMock: HttpTestingController;

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [HttpClientTestingModule],
            providers: [
                TestService
            ]
        });
        service = TestBed.inject(TestService);
        httpMock = TestBed.inject(HttpTestingController);
    });

//...
const httpRequest = httpMock.expectOne('any-url');

1 Comment

A mock is supposed to give an answer to a request.
3

If I understand your question correctly, you want to create your frontend services before your backend, but you still want to use promises / observables. You can use of for that:

import { of } from 'rxjs';
//emits any number of provided values in sequence
const source = of(1, 2, 3, 4, 5);
//output: 1,2,3,4,5
const subscribe = source.subscribe(val => console.log(val));

from https://www.learnrxjs.io/operators/creation/of.html

Comments

3

in order to fake the backend server response, you need to create a service that implements the HttpInterceptor interface

https://medium.com/@lanoTechno/intro-to-angular-http-interceptors-and-how-to-create-backendless-app-with-them-3593f6552b3a

Comments

2

Option 1:

import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

describe('ContinentService', () => {
let service: ContinentService;

beforeEach(() => {
    TestBed.configureTestingModule({ imports: 
    [HttpClientTestingModule] });
    service = TestBed.inject(ContinentService);
});

it('should be created', async () => {
expect(service).toBeTruthy();
const httpMock = TestBed.inject(HttpTestingController);

const response = 
  {
    id: 'some-id',
    data: 'fancy profile data'
  };

  // unfortunately, you can't use async/await!
  // const result = await service.countries$.toPromise();
  service. getProfile().subscribe((result) => {
    expect(result[0].name).toBe('España');
  });

   const mockRequest = httpMock.expectOne('go/profile/get');
   mockRequest.flush(countries);
 });
});

More information:

https://www.beyondjava.net/jest-mocking-an-angular-service

Comments

-2

You can put the response json in the asset folder and do the testing.

For example create a test.json file under assets/json and change your url accordingly

private getProfile() {
    this.http
      .get('assets/json/test.json', {withCredentials: true})
      .subscribe((profile: Profile) => {
        this.user.profile = profile;
        this.updateLineMsgs();
      });
  }

You can also configure the url to be selected based on the environment variable so that in the prod build actual url will be taken and in dev the dummy one.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.