繁体   English   中英

Angular 测试 - 如何使用扩展基类测试数据服务

[英]Angular Testing - how to test Data Service with extended base class

我很难设置我的数据服务的测试,我正在尝试使用这些文章中定义的HttpClientTestingModule使用Angular HttpClient API 进行测试,来自这个SO 问题,并且还尝试从这篇文章中inject测试 HttpClient但我可以不让它工作。

我相信我的问题来自这样一个事实,即我有一个使用 3 个服务提供程序的全局DataService (来自ngx-translate HttpClientNGXLoggerTranslateService )。 然后我有多个数据服务扩展了全球DataService像这样

@Injectable()
export class UserDataService extends DataService {
  constructor(protected http: HttpClient, protected logger: NGXLogger, protected translate: TranslateService) {
  super(http, logger, translate);
  this.url = `api/users`;
}

getUsers(): Observable<Users[]> {
  return super.getAll<User[]>(this.url);
}

如您所见,每个扩展数据服务(如UserDataServices )负责将 3 个必要的依赖项注入到super调用中。

我正在尝试使用以下代码编写我的测试,这是使用Jest完成的

describe('User Data Service', () => {
  let dataService: TemplateDataService;
  let httpTestingController: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
        TranslateModule.forRoot(),
        LoggerModule.forRoot({ level: NgxLoggerLevel.ERROR, serverLoggingUrl: 'api/logging', serverLogLevel: NgxLoggerLevel.ERROR }),
      ],
      providers: [
        UserDataService
      ]
    });
    dataService = TestBed.get(UserDataService);
    httpTestingController = TestBed.get(HttpTestingController);
  });

it('should return an Observable<User[]>', () => {
  const dummyUsers = [
    { login: 'John' },
    { login: 'Doe' }
  ];

  dataService.getAll().subscribe((users: User[]) => {
    expect(users.length).toBe(2);
    expect(users).toEqual(dummyUsers);
  });

  const req = httpTestingController.expectOne(`api/users`);
  expect(req.request.method).toBe('GET');
  req.flush(dummyUsers);
});

它不断抛出以下错误

Unexpected value 'HttpClientModule' imported by the module 'HttpClientTestingModule'. Please add a @NgModule annotation.

我也试过这段代码,但我得到了同样的错误

it(
  'should get users',
  inject(
    [HttpTestingController, NGXLogger, TranslateService, DataService],
    (
      httpMocker: HttpTestingController,
      logger: NGXLogger,
      translate: TranslateService,
      dataServicer: DataService
    ) => {
      // ...our test logic here
    }
  )
);

我对单元测试相当陌生(我上周开始)并且我完全无法测试我的任何数据服务(从好的方面来说,我可以使用数据服务模拟测试组件,但是我”我也想测试这些数据服务)。

在技​​术方面,该项目使用Angular: ^7.2.10jest: ^23.6.0

编辑

我忘了提到DataService也是一个服务,我也尝试将它添加到beforeEach()providers ,但我仍然遇到相同的错误( Unexpected value 'HttpClientModule'... )。 如下所示

beforeEach(() => {
  TestBed.configureTestingModule({
    imports: [
      HttpClientTestingModule,
      TranslateModule.forRoot(),
      LoggerModule.forRoot({ level: NgxLoggerLevel.ERROR, serverLoggingUrl: 'api/logging', serverLogLevel: NgxLoggerLevel.ERROR }),
    ],
    providers: [
      DataService,
      UserDataService
    ]
  });
});

另外,为了对DataService更多概述,这里是它的精简版。

export class DataService {
  constructor(protected http: HttpClient, protected logger: NGXLogger, protected translate: TranslateService) {}

  get<T>(id?: string, options?: HttpOptions): Observable<T> {
    const caller = findCaller(new Error());
    const uriWithId = id ? `/${id}` : '';
    const requestUrl = this.addGlobalQueryParams(`${this.url}${uriWithId}`);
    this.logger.debug(`DataService - GET method [${caller}] - START - URL:: ${requestUrl}`);

    return this.http.get<T>(requestUrl, options).pipe(map((response: any) => {
      this.logger.debug(`DataService - GET method [${caller}] - END - URL:: ${requestUrl} - Response:: `, response);
      return response;
    }));
  }

  getAll<T>(url?: string, options?: HttpOptions): Observable<T> {
    const caller = findCaller(new Error());
    if (url) {
      this.logger.debug(`DataService - POST method [${caller}] - START - URL:: `, url);
      return this.http.post<T>(url).pipe(map((response: any) => {
        this.logger.debug(`DataService - POST method [${caller}] - END - URL:: ${url} - Response:: `, response);
        return response;
      }));
    }
  }
}

编辑 2

我想我要的是如何进行单元测试的扩展级,这实际上是要求在角回购这里,但从来没有回答关闭,因为它不是一个问题,但更多的是问题。

首先,您不需要在测试中执行以下操作。

 providers: [
   UserDataService
 ]

由于您正在测试UserDataService本身,因此在设置 TestBed 后执行以下操作就足够了。

dataService = TestBed.inject(UserDataService); //TestBed.get(UserDataService);

另一件要更改的事情是使您的基类可注入。

@Injectable()
export class DataService {...}

我知道这听起来很愚蠢,但显然角度 DI 似乎也需要这样做。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM