测试HTTPClient Angular 4“预期未定义要定义”

时间:2017-10-19 12:11:06

标签: angular integration-testing karma-jasmine

测试Angular 4 HTTPClient

遵循此post

在服务中

 getBlogs(){
     return this._http.get(this.blogsURL+'blogs')
          .map((result: Response ) => {
               this.blogs  = result['blogs'];
               return this.blogs;
     })
 }

然后测试: 我开始将服务和HttpTestingController注入到它的块中,但是将它们放入之前也是如此。

调用request.flush时出现问题,因此触发了subscribe方法,它们没有返回结果

import { TestBed, inject } from '@angular/core/testing';
import { HttpClientModule } from '@angular/common/http';
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';

import { BlogsService } from './blogs.service';
import { Blog } from '../models/blog';


describe('BlogsService', () => {
  let service:BlogsService;
  let blogsURL:string;
  let httpMock:HttpTestingController;
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [BlogsService],
      imports: [HttpClientTestingModule]
    });
    service = TestBed.get(BlogsService);
    httpMock = TestBed.get(HttpTestingController);
    blogsURL = 'http://localhost:3000/'
  });



 it('#getBlogs should return data',() => {
   service
       .getBlogs()
       .subscribe(result => {
         expect(result).toBeDefined();
         expect(result.length).toBe(2);
         expect(result).toEqual([
          {
            id: 1,
            name: 'Foo',
            numSales: 100
          }, {
            id: 2,
            name: 'Bar',
            numSales: 200
          }
        ]);
       });


     // look up our request and access it
     const request = httpMock.expectOne(blogsURL+'blogs');
     // verify it is a GET
     expect(request.request.method).toEqual('GET');

     // Now, provide the answer to the caller above,
     // flushing the data down the pipe to the caller and
     // triggering the test's subscribe method
     request.flush([
          {
            id: 1,
            name: 'Foo',
            numSales: 100
          }, {
            id: 2,
            name: 'Bar',
            numSales: 200
          }
        ]);
     //
    //  // make sure it actually got processed...
     httpMock.verify();
   });


});

2 个答案:

答案 0 :(得分:1)

假设您从网址正确返回了数据,您似乎忘记了服务中result.json()功能中的map。 Angular http服务返回一个对象Response,您需要调用它的json函数来获取您的实际json对象,然后您可以返回您的数据。将您的getBlogs方法更改为以下

 getBlogs(){
     return this._http.get(this.blogsURL+'blogs')
      .map((result: Response ) => {
           const resp = result.json();
           this.blogs  = resp['blogs'];
           return this.blogs;
      })
 }

答案 1 :(得分:1)

经过一些试验和错误(主要是错误)

我已经解决了这个问题,我认为对测试HTTPClient有了更好的理解。

让我们从数据库服务器返回的内容开始

{message: 'Success', blogs: blogs}

带有消息的json对象和我的博客数组,名为blogs

接下来服务中的函数名为getBlogs

两条重要的路线是:

  this.blogs  = res['blogs'];
  return this.blogs;

这样做是从结果中提取博客数组,添加到var this.blogs然后返回它。

我一直忘记的是,我正在测试我服务中的实际功能,而不是一个单独的实体,因此测试需要博客 要返回,这就是为什么我得到一个未定义的错误,所以我添加了一个模拟博客数组:

  blogs = [{_id: '1234',title: 'title1-test', vidUrl: 'XpiipWULkXk', script:'Some test script'}, {_id: '12345',title: 'title2', vidUrl: 'XpiipWULkXk', script:'Some test script2'}];

然后在flush语句中

request.flush({message:"Success", blogs:blogs});

因为这需要模拟从服务器返回的内容,所以代码可以提取它。

完整代码:

import { TestBed, inject } from '@angular/core/testing';
import { HttpClientModule } from '@angular/common/http';
import {HttpClientTestingModule, HttpTestingController} from '@angular/common/http/testing';

import { BlogsService } from './blogs.service';
import { Blog } from '../models/blog';


describe('BlogsService', () => {
  let service:BlogsService;
  let blogsURL:string;
  let httpMock: HttpTestingController;
  let blogs:Blog[];

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [BlogsService],
      imports: [HttpClientTestingModule]
    });
    service = TestBed.get(BlogsService);
    httpMock = TestBed.get(HttpTestingController);
    blogsURL = 'http://localhost:3000/';
    blogs = [{_id: '1234',title: 'title1-test', vidUrl: 'XpiipWULkXk', script:'Some test script'}, {_id: '12345',title: 'title2', vidUrl: 'XpiipWULkXk', script:'Some test script2'}];

  });


  it('#getBlogs should return data',() => {
    service
        .getBlogs()
        .subscribe(results => {
          expect(results).toBeDefined();
          //has to be what is returned by the function
          expect(results).toEqual(blogs);
          console.log(results)

        });
      // look up our request and access it
      const request = httpMock.expectOne(blogsURL+'blogs');
      // verify it is a GET
      expect(request.request.method).toEqual('GET');

      request.flush({message:"Success", blogs:blogs});
     //  // make sure it actually got processed...
      httpMock.verify();
    });


});