简体   繁体   English

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

[英]Angular2 - Unit test case not able to Mock Service

I am not able to mock user service, other service which I mocked are working fine.我无法模拟用户服务,我模拟的其他服务工作正常。 If I am commenting user service then unit test case is working fine.如果我评论用户服务,那么单元测试用例工作正常。 There are many components which are using user service.有许多组件正在使用用户服务。 Unit test cases for all those components are not working in which user service is injected.所有这些组件的单元测试用例在注入用户服务的情况下都不起作用。

Error : Can't resolve all parameters for AlertService: ([object Object], ?, [object Object], [object Object]).错误:无法解析 AlertService 的所有参数:([object Object], ?, [object Object], [object Object])。

Code for testing Alert service :测试警报服务的代码:

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();
  }));
});

Code for Actual service :实际服务代码:

@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([]);
    }
}

Here is the bug.这是错误。 I am using like this :我是这样使用的:

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

Angular is not able to resolve it properly. Angular 无法正确解决它。 I write it like below and it worked我像下面这样写并且它起作用了

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

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

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

I would suggest you either use jasmine.createObjectSpy or the following:我建议您使用jasmine.createObjectSpy或以下内容:

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

When testing services I generally use this pattern.在测试服务时,我通常使用这种模式。 It usesReflectiveInjector.resolveAndCreate .它使用ReflectiveInjector.resolveAndCreate

Resolves an array of providers and creates an injector from those providers解析一组提供者并从这些提供者中创建一个注入器

  • The beforeEach will call this before each test ( it ) and populate the local backendAlertService variable. beforeEach将在每次测试 ( it ) 之前调用it并填充本地backendAlertService变量。
  • The test code has full access to the MockBackend using this.backend测试代码已经完全进入到MockBackend使用this.backend
  • The test code can check anything on the last connection using this.lastConnection测试代码可以使用this.lastConnection检查上次连接上的任何this.lastConnection
  • The test code has access to all user defined types that are injected.测试代码可以访问所有注入的用户定义类型。 The instances in this test setup are this.userService , this.loggerService , and this.configService .此测试设置中的实例是this.userServicethis.loggerServicethis.configService

Code:代码:

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();
  }));  
});

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

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