【问题标题】:Angular Testing Getting Actual HTTP ResponseAngular 测试获取实际的 HTTP 响应
【发布时间】:2018-09-08 01:20:17
【问题描述】:

我是角度单元测试的新手。我想做的是从我的 API 中获得实际结果。我检查了this 文档,但据我所知,我应该创建模拟响应。这是我的代码,

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();
});

当我在控制台中写入结果时,它会写入“testData”而不是“data”。正如我之前所说,我想从我的 API 中获得实际结果,而不是模拟结果。对不起,如果这是一个愚蠢的问题,但我该怎么做?感谢您的建议。

【问题讨论】:

    标签: angular unit-testing angular-http angular-test


    【解决方案1】:

    这是获取真实数据的有效解决方案

    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();
        });
      });
    });
    

    希望有帮助

    【讨论】:

      【解决方案2】:

      注意flush解决了请求,然后你可以使用

      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 }));
      

      【讨论】:

        【解决方案3】:

        如果您没有模拟服务调用,您实际上可以等待响应。由于这是一个异步调用,因此您必须让测试运行程序框架知道您正在等待结果。您可以通过提供done function 来做到这一点。

        示例代码:

        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.
            });
        });
        

        更多信息:https://codecraft.tv/courses/angular/unit-testing/asynchronous/#_jasmines_code_done_code_function

        【讨论】:

        • 当我这样做时,我收到如下错误:“错误:超时 - 在 jasmine.DEFAULT_TIMEOUT_INTERVAL 指定的超时内未调用异步回调。”
        • 这意味着您的 http 调用没有及时响应,或者在调用 done() fn 之前出现任何错误。
        猜你喜欢
        • 2019-02-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-04
        • 2017-02-21
        • 1970-01-01
        • 2017-03-05
        • 1970-01-01
        相关资源
        最近更新 更多