【问题标题】:Error: <spyOn> : could not find an object to spy upon for Roles()错误:<spyOn>:找不到用于监视 Roles() 的对象
【发布时间】:2019-02-03 18:21:58
【问题描述】:

我正在编写我的第一个 Angular 6 单元测试。我按照这个来源https://www.youtube.com/watch?v=lTKhB6uAmno 来构建我的测试文件,结果我遇到了我无法解决的错误。我在 SO 中找到了similar question,但不幸的是没有得到答案。请指导我解决这个错误。谢谢。这是我的文件,

component.ts

import { Component } from '@angular/core';
import { InputModel } from '../model/formInput';
import { APIService } from '../service/APIService';

@Component({
    selector: 'results-component',
    templateUrl: './result.component.html',
    styleUrls: ['./result.component.css']
})

export class ResultComponent {
    constructor(private apiService: APIService) { }
    sendTask(model: InputModel) {
        this.apiService.getRoles(model.TaskName)
            .subscribe(
                res => {
                    console.log(res)
                }, err => { console.log(err) });
    }
}

service.ts

import {Injectable} from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { ApiResponse } from '../model/ApiResponse';
import { Observable, throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

@Injectable()

export class APIService{

    private url:string = 'http://localhost:1/api/default';
    result:ApiResponse;
    private http:HttpClient;

    constructor(){}

    getRoles(taskName:string):Observable<ApiResponse>{
        var params = this.getParams(taskName);
        return this.http.get<ApiResponse>(this.url,{ params })
        .pipe(
            map((data:ApiResponse)=>data),
            catchError((err:ApiResponse)=>throwError(err))
            )
        }

    private getParams(taskName:string){
        let param = new HttpParams().set('taskName', taskName);
        return param;
    }
}

component.spec.ts

import { ResultComponent } from "./result.component";
import {ComponentFixture, TestBed, inject} from '@angular/core/testing';
import { APIService } from "../service/APIService";
import { of } from "rxjs";
import { ApiResponse } from "../model/ApiResponse";
import { InputModel } from "../model/formInput";
import { HttpClientTestingModule } from "@angular/common/http/testing";

describe('ResultComponent', ()=>{
    let fixture:ComponentFixture<ResultComponent>;
    let component:ResultComponent;
    let apiService:APIService;
    let model:InputModel = new InputModel();
    let mockResponse : ApiResponse=
    {
        code:'0',
        data:{
            permissionsList:[
                {
                    orgRoles:'Edit Access TRUE',
                    roleType:'OPTIONAL'
                }
            ]
        },
        message:'',
        status:'success'
    };

    beforeEach(()=>{
        TestBed.configureTestingModule({
            imports:[HttpClientTestingModule],
            declarations:[ResultComponent],
            providers:[APIService]//,
            //{provide:HttpClient}]
        }).compileComponents();

        fixture = TestBed.createComponent(ResultComponent);
        component = fixture.componentInstance;
        apiService=TestBed.get(APIService);

        model.TaskName='Edit';
    });

    it('test service response', ()=>{
        spyOn(apiService, 'getRoles').and.returnValue(of(mockResponse));
         component.sendTask(model);
        expect(apiService.getOrgRoles).toHaveBeenCalled();
    });
})

如果我使用虚假服务,则单元测试工作正常。我无法找出我在规范文件中遗漏的内容。

【问题讨论】:

  • 您遇到的错误是什么?
  • 错误::无法为 getRoles() 找到要监视的对象 用法:spyOn(, )

标签: angular typescript jasmine


【解决方案1】:

您无需使用spyOnmethod 即可轻松完成此操作。

而不是为您的服务创建spy object,并在提供者数组中提供该间谍对象作为服务。

describe('Result component tests', () => {

  let fixture: ComponentFixture<ResultComponent>;
  let component: ResultComponent;

  let apiService: APIService;
  let spyApiService: jasmine.SpyObj<APIService>;

  let getRolesSubject;
  let mockResponse: ApiResponse =
    {
      code: '0',
      data: {
        permissionsList: [
          {
            orgRoles: 'Edit Access TRUE',
            roleType: 'OPTIONAL'
          }
        ]
      },
      message: '',
      status: 'success'
    };

  beforeEach(async(() => {
    getRolesSubject = new Subject();

    spyApiService = jasmine.createSpyObj('APIService', ['getRoles']);
    spyApiService.getRoles.and.returnValue(getRolesSubject.asObservable());

    TestBed.configureTestingModule({
      declarations: [ResultComponent],
      providers: [
        {provide: APIService, useValue: spyApiService},
      ],
      schemas: [NO_ERRORS_SCHEMA]
    }).compileComponents().then(() => {
      fixture = TestBed.createComponent(ResultComponent);
      component = fixture.componentInstance;

      apiService = TestBed.get(APIService);
    });
  }));


  it('Should invoke getRoles of api service when ...', () => {
    component.sendTask(model);
    getRolesSubject.next(mockResponse);
    expect(apiService.getRoles).toHaveBeenCalled();
  });

});

我正在使用 subject 从服务中将值作为可观察值返回。

getRolesSubject.next(mockResponse);

认为您在 subscribe 方法中的方法很少。现在你也可以测试它们了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-27
    • 1970-01-01
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    • 2020-08-30
    • 2020-07-22
    • 1970-01-01
    相关资源
    最近更新 更多