【问题标题】:angular2 - how to simulate error on http.post unit testangular2 - 如何在 http.post 单元测试中模拟错误
【发布时间】:2016-07-14 06:28:13
【问题描述】:

我正在编写一个带有 HTTP.post 调用的登录方法的 Uni-test,例如:

this.http.post( endpoint, creds, { headers: headers})
        .map(res => res.json())
        .subscribe(
        data => this.onLoginComplete(data.access_token, credentials),  
        err => this.onHttpLoginFailed(err),
        () => this.trace.debug(this.componentName, "Login completed.")
    );

问题是我无法模拟错误分支;每次调用 onLoginComplete 方法;

这是我的测试:

it("check that  Atfer Login, console show an error ", inject(
  [TraceService, Http, MockBackend, WsiEndpointService],
  (traceService: TraceService, http: Http, 
   backend: MockBackend, wsiEndpoint: WsiEndpointService) => {

  let tokenTest: number =  404 ;

  let response: ResponseOptions = null {} // i think i have to modify this

  let connection: any;

  backend.connections.subscribe((c: any) => connection = c);

  let authService: AuthService = new AuthService(http, Service1, Service2);

  authenticationservice.login({ "username": "a", "password": "1" });

  connection.mockRespond(new Response(response));

  expect(ERROR);

}));

再次感谢大家。

【问题讨论】:

    标签: unit-testing http post angular


    【解决方案1】:

    你可以模拟这样的错误:

    connection.mockError(new Response(new ResponseOptions({
        body: '',
        status: 404,
    })));
    

    我创建了一个小班

    import {ResponseOptions, Response} from '@angular/http';
    
    export class MockError extends Response implements Error {
    
        name: any;
        message: any;
    
        constructor(status: number, body: string = '') {
            super(new ResponseOptions({status, body}));
        }
    }
    

    可以这样使用

    connection.mockError(new MockError(404));
    

    【讨论】:

      【解决方案2】:

      首先你需要用MockBackend 覆盖XHRBackend 类:

      describe('HttpService Tests', () => {
        beforeEachProviders(() => {
          return [
            HTTP_PROVIDERS,
            provide(XHRBackend, { useClass: MockBackend }),
            HttpService
          ];
        });
      
        (...)
      });
      

      注意HttpService 是使用Http 对象的服务,我想测试。

      然后你需要注入 mockBackend 并订阅它的 connections 属性。发送请求时,会调用相应的回调,您可以指定响应元素,如正文。服务将接收此响应作为调用的响应。因此,您将能够基于此测试您的服务方法。

      下面我描述如何测试HttpServicegetItems方法:

      it('Should return a list of items', inject([XHRBackend, HttpService, Injector], (mockBackend, httpService, injector) => {
        mockBackend.connections.subscribe(
          (connection: MockConnection) => {
            connection.mockRespond(new Response(
              new ResponseOptions({
                body: [ { id: '1', label: 'item1' }]
              })));
            });
      
        httpService.getItems().subscribe(
          items => {
            expect(items).toEqual([ { id: '1', label: 'item1' }]);
          });
        });
      });
      

      这里是HttpServicegetItems方法的代码:

      @Injectable()
      export class HttpService {
        constructor(private http:Http) {
        }
      
        getItems(): Observable<any[]> {
          return this.http.get('/items').map(res => res.json());
        }
      }
      

      要模拟错误,只需使用mockError 方法而不是mockResponseone:

        mockBackend.connections.subscribe(
          (connection: MockConnection) => {
            connection.mockError(new Error('some error'));
          });
      

      【讨论】:

      • 小问题:除了字符串之外,如何使用 mockError 添加错误 http 状态代码(404、422、500 等)?就我而言,某些服务器响应不会返回任何内容。出于某种原因,我还没有找到可以在任何地方显示这一点的示例。
      • @LucioMollinedo 这是因为当前 RC 不支持它。请参阅 github.com/angular/angular/pull/8961 以获取错误修复以使其可用。与此同时,糟糕的单元测试将不得不再次受到打击。
      • 我想知道这个解决方案是否可以应用于当前版本的angular(2.4)?我试图在这里调整它:stackoverflow.com/questions/42192911 无济于事......有人可以建议吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-10
      • 2017-04-19
      • 2017-06-14
      • 2017-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多