Angular Testing Getting Actual HTTP Response

别说谁变了你拦得住时间么 提交于 2021-01-27 19:46:29

问题


I'm new to angular unit testing. What I want to do is getting actual results from my API. I checked this documentation but as I understand, I should create mock responses. Here is my code,

myService.ts:

...

public GetAll = (apiname: string): Observable<Object> => {

return this._http.get("foo/" + apiname,{headers:this.options}); //this.options = newHttpHeaders({'ContentType':'application/json','Accept':'application/json'});
}
...

myService.spec.ts:

...

beforeEach(() => {
    TestBed.configureTestingModule({
    imports: [
        HttpClientModule,
        HttpClientTestingModule
    ],
    providers: [
        MyService
    ]
    });  
});

afterEach(inject([HttpTestingController], (backend: HttpTestingController) => {
    backend.verify();
}));

it('GetAll() should work', () => {

    const testData = {id: "123"};

    service.GetAll("items").subscribe(data => { 
        //console.log(JSON.stringify(data));
    });

    const req = httpTestingController.expectOne('foo/items');
    expect(req.request.method).toEqual('GET');

    req.flush(testData);
    httpTestingController.verify();
});

When I write the result in console, it writes 'testData' instead of 'data'. As I said before, I want to get actual result from my API, not mock result. Sorry if it is a silly question but how can I do that ? Thanks for advice.


回答1:


Here is a working solution to get a real data

auth.service.te

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
interface Post {
  userId: number;
  id: number;
  title: string;
  body: string;
}
@Injectable({
  providedIn: 'root',
})
export class AuthService {
  constructor(private http: HttpClient) {}
  getPost(postId: number): Observable<Post> {
    return this.http.get<Post>(
      `https://jsonplaceholder.typicode.com/posts/${postId}`
    );
  }
}

auth.service.spec.ts

import { TestBed } from '@angular/core/testing';
import { AuthService } from './auth.service';
import { HttpClientModule } from '@angular/common/http';
interface Post {
  userId: number;
  id: number;
  title: string;
  body: string;
}
describe('AuthService', () => {
  let service: AuthService;
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientModule],
    });
    service = TestBed.inject(AuthService);
  });
  it('should get the data successfully', (done: DoneFn) => {
    service.getPost(1).subscribe((post: Post) => {
      console.log('data is ', post);
      expect(post.id).toEqual(1);
      done();
    });
  });
});

Hope is helps




回答2:


If you are not mocking the service call, you can actually wait for the response. Since this is an async call, you will have to let the test runner framework know that you are waiting for the result. You can do that with providing a done function.

Sample code:

it('GetAll() should work', (done) => {
    service.GetAll("items").subscribe(data => { 
        expect(data).toContain("something");
        //expect ...

        done();             // <= done fn invoked. This marks end of test case.
    });
});

More info: https://codecraft.tv/courses/angular/unit-testing/asynchronous/#_jasmines_code_done_code_function




回答3:


notice that flush resolves the request , then you can use

service.GetAll(data).subscribe((response : HttpResponse<any>) => {
    expect(response.status).toBe(200);          
    expect(response.body).toEqual(testData);
});

const req = httpTestingController.expectOne('foo/items');
expect(req.request.method).toEqual('GET');
req.flush(new HttpResponse({ status: 200, body: testData }));


来源:https://stackoverflow.com/questions/49550041/angular-testing-getting-actual-http-response

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!