如何在jasmine中测试map()响应JSON

时间:2018-05-29 07:52:15

标签: angular unit-testing typescript jasmine

在jasmine服务中测试map()响应JSON的最佳方法是什么。

在这段代码中,我可以从ws获取所有类型的警报。现在我想测试这项服务。为此我尝试了一些代码,如下所示。

 public typegetall(): Observable<Alarm[]> {
        ...
    return this.http.get(Api.getUrl(Api.URLS.typegetall), {
      headers: headers
    })
      .map((response: Response) => {
        let res = response.json();
        if (res.StatusCode === 1) {
          this.auth.logout();
        } else {
          return res.StatusDescription.map(alarm => {
            return new Alarm(alarm);
          });
        }
      });
  }

我尝试过这个单元测试:

    describe(`Service`, () => {
         beforeEach(() => {
            TestBed.configureTestingModule({
                declarations: [AlarmsTableComponent],
                imports: [],
                providers: [
                    { provide: AlarmsService]
            }).compileComponents()
                .then(() => {
                    myComponent = TestBed.createComponent(AlarmsTableComponent).componentInstance;
                    myService = TestBed.get(AlarmsService);
                });
        });
               afterEach(inject([HttpTestingController], (backend: HttpTestingController) => {
              backend.verify();
        }));
             it('alarms get all', inject([AlarmsService], (alarmeservice: AlarmsService) => {
            expect(alarmeservice.typegetall());
        }));
});

你能问我一些测试的想法吗?

编辑:

it('should return reasonable json ssss', inject([AlarmsService, MockBackend], fakeAsync((service: AlarmsService, mockBackend) => {

    const mockResponse = {
        data: [
            { alarmnumber: 0, alarmdesc: 'All cats are lions' },
            { alarmnumber: 1, alarmdesc: 'Video 1' },
            { alarmnumber: 2, alarmdesc: 'Video 2' },
            { alarmnumber: 3, alarmdesc: 'Video 3' },
        ]
    };

    mockBackend.connections.subscribe(connection => {
        connection.mockRespond(new Response(
            new ResponseOptions({
                body: [
                    { alarmnumber: 0, alarmdesc: 'All cats are lions' },
                    { alarmnumber: 1, alarmdesc: 'Video 1' },
                    { alarmnumber: 2, alarmdesc: 'Video 2' },
                    { alarmnumber: 3, alarmdesc: 'Video 3' },
                ]
            })));
    });

    service.typegetall().subscribe(alarmstype => {
        console.log(alarmstype)
        expect(alarmstype.length).toBe(3);
        expect(alarmstype[0].alarmdesc).toEqual("All cats are lions");
    });

    tick();
})));

结果: 错误:无法在假异步测试中制作XHR。请求网址:http://xxxxxx/v1/products

1 个答案:

答案 0 :(得分:0)

我看到两个要测试的案例:statusCode === 1statusCode !== 1时。

第一次测试: 模拟后端将响应作为具有StatusCode属性的对象的可观察对象返回,设置为1.

您应该从logout对象为auth方法创建一个jasmine间谍。

然后,订阅typegetall()方法并在调用logout时签入此订阅。

第二次测试: 模拟后端将响应返回为具有StatusCode属性的可观察对象,设置为2并将StatusDescription属性设置为alarm数组,而不是作为报警尚未实现。

然后,使用返回数据(您的警报数组)订阅typegetall()。在此订阅中,您可以测试长度,并为每个项目测试它们是否为警报的实例。

检查official testing documentation以了解如何创建模拟回复。

第一个:

it('should call logout when statusCode is equal to 1', () => 
{
     alarmService = TestBed.get(AlarmService);
     authService = TestBed.get(AuthService);
    /* Put your mock response here, an observable of object with StatusCode set to 1 */
    spyOn(authService, 'logout');
    alarmService.typegetall().subscribe(() => {
        expect(authService.logout).toHaveBeenCalledTimes(1);
    });
}

第二个:

it('should return an array Alarm when statusCode is equal to 2', () => 
{
     alarmService = TestBed.get(AlarmService);
     authService = TestBed.get(AuthService);
    /* Put your mock response here, an observable of object with StatusCode set to 2 and StatusDescription set to an array of 3 alarm object*/
    spyOn(authService, 'logout');
    alarmService.typegetall().subscribe((alarms: Alarm[]) => {            
        expect(authService.logout).not.toHaveBeenCalled;
        expect(alarms.length).toBe(3);
        alarms.forEach(alarm => expect(jasmine.any(alarm instanceof Alarm)).toBeTruthy());
        /*
           Other expectations to check object properties values, such as :
           expect(alarms[0].aProperty).toBe(...);
        */
    });
}

要测试错误,请在服务上添加rxjs catchError运算符(learn more here):

public typegetall(): Observable<Alarm[]> {
    ...
return this.http.get(Api.getUrl(Api.URLS.typegetall), {
  headers: headers
})
  .map((response: Response) => {
    let res = response.json();
    if (res.StatusCode === 1) {
      this.auth.logout();
    } else {
      return res.StatusDescription.map(alarm => {
        return new Alarm(alarm);
      });
    }
  })
  .catchError(error => of(`An error occured: ${error}`));
}

并像这样测试:

 it('should get an error', () => 
{
     alarmService = TestBed.get(AlarmService);
    /* Create your mock response error here, an observable created with '_throw' and return a value (ex: 'shit, error !') */
    alarmService.typegetall().subscribe(error => expect(error).toBe('shit, error !'));
}