Angular2 - 无法模拟服务的单元测试用例

时间:2017-10-27 06:16:43

标签: angular unit-testing

我无法模拟用户服务,我嘲笑的其他服务工作正常。如果我正在评论用户服务,那么单元测试用例正常。有许多组件正在使用用户服务。所有这些组件的单元测试用例不能用于注入哪些用户服务。

错误:无法解析AlertService的所有参数:([object Object],?,[object Object],[object Object])。

测试警报服务的代码:

import { TestBed, inject } from '@angular/core/testing';

import { BackendAlertService } from './backend-alert.service';
import { Injectable } from '@angular/core';
import { HttpModule, ConnectionBackend } from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';
import { ConfigService, LoggerService, UserService } from '../../shared/services';
import { Observable } from 'rxjs';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HttpClient } from '@angular/common/http';

@Injectable()
class MockUserService {
  private data$: Observable<Object>;
  readonly user$: Observable<any>;
  readonly privilege$: Observable<any[]>;

  constructor() {
    this.data$ = Observable.of({ me: 'JindaR', fname: 'rohit' });
    this.user$ = Observable.of({ me: 'JindaR' });
    this.privilege$ = Observable.of([{ testing: 'true' }]);
  }

  hasPrivilege(privilege): Observable<boolean> {
    return Observable.of(true);
  }

}


@Injectable()
class MockConfigService {
  url$(url) {
    return Observable.of('testing.com');
  }
}

@Injectable()
class MockLoggerService {

}

fdescribe('BackendAlertService', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpModule, HttpClientTestingModule],
      providers: [
        BackendAlertService,
        HttpTestingController,
        { provide: UserService, useClass: MockUserService },
        { provide: ConnectionBackend, useClass: MockBackend },
        { provide: ConfigService, useClass: MockConfigService },
        { provide: LoggerService, useClass: MockLoggerService }
      ]
    });
  });

  it('should be created', inject([BackendAlertService], (service: BackendAlertService) => {
    expect(service).toBeTruthy();
  }));
});

实际服务代码:

@Injectable()
export class BackendAlertService {

    constructor(
        private configService: ConfigService,
        private userService: UserService,
        private http: Http,
        private logger: LoggerService) { }

    /** Get Alerts */
    get(): Observable<Alert[]> {
        return Observable.of([]);
    }
}

3 个答案:

答案 0 :(得分:1)

这是错误。我这样使用:

import { ConfigService, LoggerService, UserService } from '../../shared/services'

Angular无法正确解析它。我写的如下,它有效

import { ConfigService} from '../../shared/services/config.service';

import { LoggerService } from '../../shared/services/logger.service';

import { UserService } from '../../shared/services/user.service';

答案 1 :(得分:0)

我建议您使用jasmine.createObjectSpy或以下内容:

{
 provide: UserService,
 useValue: {
 hasPriviledge: _ => Observable.of(true),
 }
}

答案 2 :(得分:0)

测试服务时,我通常使用这种模式。它使用ReflectiveInjector.resolveAndCreate

  

解析一系列提供者并从这些提供者创建一个注入器

  • beforeEach会在每次测试(it)之前调用此方法并填充本地backendAlertService变量。
  • 测试代码可以使用MockBackend
  • 完全访问this.backend
  • 测试代码可以使用this.lastConnection
  • 检查最后一个连接上的任何内容
  • 测试代码可以访问注入的所有用户定义类型。此测试设置中的实例为this.userServicethis.loggerServicethis.configService

代码:

import { ReflectiveInjector } from '@angular/core';
import { fakeAsync, tick } from '@angular/core/testing';
import { BaseRequestOptions, ConnectionBackend, Http, RequestOptions } from '@angular/http';
import { Response, ResponseOptions, RequestMethod } from '@angular/http';
import { MockBackend } from '@angular/http/testing';

describe('Backend alert service tests', () => {

    var backendAlertService: BackendAlertService = null;

    beforeEach(() => {
        this.injector = ReflectiveInjector.resolveAndCreate([
            { provide: ConnectionBackend, useClass: MockBackend },
            { provide: RequestOptions, useClass: BaseRequestOptions },
            { provide: UserService, useClass: MockUserService },
            { provide: ConfigService, useClass: MockConfigService },
            { provide: LoggerService, useClass: MockLoggerService }
            Http,
            BackendAlertService
        ]);
        backendAlertService = this.injector.get(BackendAlertService) as BackendAlertService;
        this.backend = this.injector.get(ConnectionBackend) as MockBackend;
        this.backend.connections.subscribe((connection: any) => this.lastConnection = connection);

        // injected services/types that you want access to in your tests
        this.userService = this.injector.get(UserService) as UserService;
        this.loggerService = this.injector.get(LoggerService) as LoggerService;
        this.configService = this.injector.get(ConfigService) as ConfigService;
    });

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

  it('should get something', fakeAsync(() => {
    var results: Alert[];
    backendAlertService.get().subscribe(serviceResults => results = serviceResults);
    tick();
    expect(results).toBeDefined();
  }));  
});