使用TestBed为具有依赖关系的Angular Service创建测试用例

时间:2018-11-22 11:13:48

标签: angular typescript testing karma-jasmine

美好的一天。

当前在角度框架中运行项目。我正在尝试为具有依赖项的服务编写测试用例,但显然不了解如何构建它。下面是有问题的两个类。

这是LoginService

@Injectable({
  providedIn: 'root'
})
export class LoginService implements CanActivate, OnInit {

  constructor(private router: Router,
              private httpClient: HttpClient,
              private cookieService: CookieService) { }

这是LoginService的测试类:

import {Router} from '@angular/router';
import {CookieService} from 'angular2-cookie/core';
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {LoginService} from './login.service';
import {HttpClient} from '@angular/common/http';

describe('Service: LoginService', () => {

  let router: Router;
  let httpClient: HttpClient;
  let cookieService: CookieService;
  let service: LoginService;
  let fixture: ComponentFixture<LoginService>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [LoginService],
      providers: [Router, HttpClient, CookieService]
    });

    fixture = TestBed.createComponent(LoginService);
    service = fixture.componentInstance;
    router = TestBed.get(Router);
    httpClient = TestBed.get(HttpClient);
    cookieService = TestBed.get(CookieService);
  });

  it('should return true from isLoggedIn when token is set', function () {
    spyOn(cookieService, 'get').and.returnValue('true');
    expect(service.isLoggedIn()).toBeTruthy();
  });
});

很简单,因为我正在尝试。我得到的错误是:

Error: Unexpected value 'LoginService' declared by the module 'DynamicTestModule'. Please add a @Pipe/@Directive/@Component annotation.
    at syntaxError (http://localhost:9876/node_modules/@angular/compiler/fesm5/compiler.js?:2547:1)

基本上我的意图是注入LoginService的依赖项,然后在我认为合适的情况下在各个测试中使用spyOn方法破坏流量。

朝正确方向轻推将不胜感激。如果记录了解决方案,请进行链接。

使用TestBed时,与组件相比,服务的处理方式是否有所不同?老实说,我不确定如何解释错误,因为服务为什么会有这些注释?

阅读@ Dream88后进行编辑

我的问题的解决方案:

import {Router} from '@angular/router';
import {CookieService} from 'angular2-cookie/core';
import {LoginService} from './login.service';
import {HttpClient, HttpClientModule} from '@angular/common/http';
import {AppRoutingModule} from '../../app-routing.module';
import {TestBed} from '@angular/core/testing';
import {AppModule} from '../../app.module';

describe('Service: LoginService', () => {

  let router: Router;
  let httpClient: HttpClient;
  let cookieService: jasmine.SpyObj<CookieService>;
  let service: LoginService;

  beforeEach(() => {
    const cookieServiceSpy = jasmine.createSpyObj('CookieService', ['get']);
    TestBed.configureTestingModule({
      imports: [
        AppModule,
        AppRoutingModule,
        HttpClientModule
      ],
      providers: [LoginService, {
        provide: CookieService, useValue: cookieServiceSpy
      }]
    });

    router = TestBed.get(Router);
    httpClient = TestBed.get(HttpClient);
    cookieService = TestBed.get(CookieService);
    service = new LoginService(router, httpClient, cookieService);
  });

  it('should return true from isLoggedIn when token is set', function () {
    cookieService.get.and.returnValue('true');
    expect(service.isLoggedIn()).toBeTruthy();
  });
});

长话短说-我不知道自己在打字什么。在理解了底层实现之后,很简单。谢谢你的轻推。将Dream88标记为正确。

我问自己产品代码如何工作。 H如何注入服务。区分服务的内容(@Injectable)。这暗示了导入和提供程序中应该包含什么。

关于。

1 个答案:

答案 0 :(得分:0)

这不能用作:fixture = TestBed.createComponent(LoginService);应该创建component,即带有注释@component的东西。使用@service并不意味着呈现UI。因此,错误。

测试服务应该是简单测试功能的一种情况,不需要TestBed。仅在要测试使用所述服务的组件时才需要执行此操作,在这种情况下,您需要将其添加到提供程序列表中。

仅用于测试服务,请查看Angular Doc