Angular服务测试不通过

问题描述 投票:1回答:1

我有一个服务,它使用json-server作为我的数据库。我可以确认我的服务工作,因为我可以在一个组件中返回我的响应。但是我在尝试让Jasmin单元测试工作时遇到了这样的问题。

这是我的 receipt-data-public.spec.ts 文件。

import { ReceiptsDataPublic } from './receipts-data-public';
import { TestBed, fakeAsync, inject } from '@angular/core/testing';
import {
  HttpClientTestingModule,
  HttpTestingController,
} from '@angular/common/http/testing';
import { Receipt } from '../classes/receipt';
import { HttpClient } from '@angular/common/http';

describe('ReceiptsDataPublic', () => {
  let httpTestingController: HttpTestingController;
  let service: ReceiptsDataPublic;
  let httpClient: HttpClient;

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

    // We inject our service (which imports the HttpClient) and the Test Controller
    httpClient = TestBed.get(HttpClient);
    httpTestingController = TestBed.get(HttpTestingController);
    service = TestBed.get(ReceiptsDataPublic);
  });

  beforeEach(() => {
    service = TestBed.get(ReceiptsDataPublic);
  });

  afterEach(() => {
    httpTestingController.verify();
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });

  it('should call getDevReceipts', () => {
    const serviceSpy = spyOn(service as ReceiptsDataPublic, 'getDevReceipts');
    service.getDevReceipts();
    expect(serviceSpy.calls.count()).toBe(1);
  });

  it('should call getReceipts', () => {
    const serviceSpy = spyOn(service as ReceiptsDataPublic, 'getReceipts');
    service.getReceipts();
    expect(serviceSpy.calls.count()).toBe(1);
  });

  it('returned Observable should match the right data', (done: DoneFn) => {
    const receipt = {
      id: 1,
      expenseDate: "2019-04-26T15:15:56.948Z",
      description: "Id cupiditate sint et dolores molestias consequuntur necessitatibus ipsa. Qui assumenda consequuntur enim cumque eos eligendi culpa sit aspernatur. Qui molestiae voluptate sed a mollitia voluptatem rerum. Neque accusamus voluptate iusto vero illo consequuntur. Et ut at quod tenetur veritatis recusandae quia sed. Perspiciatis ipsum consequuntur neque distinctio.",
      amount: 122.00,
      imgUrl:"https://source.unsplash.com/1600x900/?product"
    };

    service.getDevReceipts()
      .subscribe(res => {
        expect(res[0].amount).toEqual(12.9);
        done();
    });

    const req = httpTestingController.expectOne('http://localhost:3000/receipts');
    expect(req.request.method).toEqual('GET');
    req.flush(receipt);
  });
});

这是我的实际收据数据-public.service.ts。

import { Injectable } from '@angular/core';
import { ReceiptsDataService } from './receipts-data.service';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';

import { Receipt } from '../classes/receipt';
import { throwError, Observable } from 'rxjs';

@Injectable()
export class ReceiptsDataPublic implements ReceiptsDataService {
  private LOCAL_REST_API_SERVER = 'http://localhost:3000/receipts';

  constructor(private httpClient: HttpClient) {}

  handleError(error: HttpErrorResponse) {
    let errorMessage = 'Unknown error!';
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      errorMessage = `Error: ${error.error.message}`;
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong,
      errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
    }
    return throwError('Something bad happened; please try again later.');
  }

  getDevReceipts(): Observable<Receipt[]> {
    return this.httpClient.get<Receipt[]>(this.LOCAL_REST_API_SERVER);
  }

  getReceipts(): Observable<Receipt[]> {
    throw new Error('Method not implemented.');
  }
}

但我一直得到下面的内容。

Karma failed test

我不明白我做错了什么,因为我是按照Angular文档来的?我如何设置我的服务测试来测试返回数据,并与收据数据进行匹配?

当我改用subscribe函数而不是toPromise()时,我得到了。

Uncaught TypeError: 无法读取未定义的抛出的属性 "金额"。

angular ionic-framework karma-jasmine angular-services
1个回答
0
投票

似乎你正在从mock中刷新一个对象。HttpClient 而不是一个数组。

你应该做的是简单地改变

req.flush(receipt);

req.flush([receipt]);

你掉进的陷阱是服务的返回类型。一定要注意,类型只是为了开发目的而存在,在运行时并不存在。将你的返回类型标记为 Observable<Receipt[]> 并不保证您会得到 ObservableReceipt[] 当你运行代码时。我假设你的代码运行得很完美,因为你的后台返回一个数组的 Receipt. 在测试中,它的工作原理不一样,因为你刷新的是一个简单的对象,而不是一个数组。在测试过程中。req.flush 成为你的后端服务。所以无论你在 req.flush你的服务会回报给你,即使它是完全不同的东西比 Receipt[]

© www.soinside.com 2019 - 2024. All rights reserved.