类型错误:无法读取未定义的 jasmine-karma 的属性“fetchData" [英] TypeError: Cannot read property 'fetchData' of undefined jasmine-karma

查看:31
本文介绍了类型错误:无法读取未定义的 jasmine-karma 的属性“fetchData"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我在 angular 7 中的第一个单元测试,我想在我的服务中测试我的方法,这个方法返回 Observable:

this is my first unit test in angular 7, i want to test my methode inside my service, this methode return Observable:

fetchData(chronoInfo: ALChrono): Observable<any> {
        // construct API parameters and URL
        var URL: string = this.urlDecoratorService.urlAPIDecorate("AL", "GetAccessChrono");

        var params = this.urlDecoratorService.generateParameters({
            year: chronoInfo.year,//Année
            month: chronoInfo.month,//Mois (peut être null)
            sortBy: chronoInfo.sortBy,// Champ de tri
            sortDirection: chronoInfo.sortDirection,//True pour inverser l'ordre de tri
            pageNumber: chronoInfo.currentPage,//Page de résultats
            pageSize: chronoInfo.pageSize//Nb enregistrements par page
        });

        return this.apiFetcher.fetchJson(URL, params);
        //retourne les AL par année & mois
    }

这个方法的测试是:

import { TestBed, async, inject } from '@angular/core/testing';
import { AnnonceChronoDetailService } from './annonce-chrono-detail.service';
import { HttpClientModule } from '@angular/common/http';
import { UrlDecoratorService } from "src/app/common/url-decorator.service";
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { APIFetcherService } from "src/app/services/common/api-fetcher.service";
import { Http, ConnectionBackend, RequestOptions, HttpModule } from "@angular/http";
import { ALChrono } from '../../common/IALChrono.interface';
import { Observable } from 'rxjs';

describe('AnnonceChronoDetailService', () => {
    let service: AnnonceChronoDetailService;
    let alChrono: ALChrono = { //it's an interface'
        year: 2012,
        month: -1,
        sortBy: 'asc',
        sortDirection: true,
        currentPage: 1,
        pageSize: 15
    }

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [HttpModule],
            providers: [
                AnnonceChronoDetailService,
                UrlDecoratorService,
                APIFetcherService,
                Http,
                ConnectionBackend]
        });
    });


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


    it('#fetchData should return value from observable', (done: DoneFn) => {
        service.fetchData(alChrono).subscribe(value => {
            expect(value).toBe('observable value');
            done();
        });
    });

});

当我执行 ng test 我在第二个测试中遇到问题 #fetchData should return value from observable ,错误是:

and when i execute ng test i have problem in the seconde test #fetchData should return value from observable , the error is :

AnnonceChronoDetailService > #fetchData should return value from observable


TypeError: Cannot read property 'fetchData' of undefined
    at <Jasmine>
    at UserContext.<anonymous> (http://localhost:9876/src/app/services/annonce-legale/annonce-chrono-detail.service.spec.ts?:41:17)
    at ZoneDelegate../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/node_modules/zone.js/dist/zone.js?:388:1)
    at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9876/node_modules/zone.js/dist/zone-testing.js?:288:1)
    at ZoneDelegate../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9876/node_modules/zone.js/dist/zone.js?:387:1)
    at Zone../node_modules/zone.js/dist/zone.js.Zone.run (http://localhost:9876/node_modules/zone.js/dist/zone.js?:138:1)
    at runInTestZone (http://localhost:9876/node_modules/zone.js/dist/zone-testing.js?:506:1)
    at UserContext.<anonymous> (http://localhost:9876/node_modules/zone.js/dist/zone-testing.js?:522:1)
    at <Jasmine>

我尝试了一些解决方案,例如添加 asyn 但问题是一样的.

i try some solutions like adding asyn but the problem was the same.

推荐答案

您在第一个规范('it' 函数)中定义了 'service',然后尝试在第二个规范中使用它.如果您想在每个规范中使用服务"变量,这是有道理的,那么我建议您在 beforeEach 函数中放置类似的内容,以便为每个规范正确定义服务:

You define 'service' in the first spec ('it' function) but then try and use it in the second. If you want to use the 'service' variable within each spec, which makes sense, then I would suggest you put something like this inside the beforeEach function to define service correctly for every spec:

service = TestBed.get(AnnonceChronoDetailService);

然后将您的第一个规范更改为以下内容:

Then change your first spec to the following:

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

现在你的第二个规范应该可以正常工作了.

Now your second spec should work as written.

为您的其他服务添加间谍.有很多方法可以做到这一点.这是一个:

Adding spies for your other services. Many ways to do this. Here is one:

describe('AnnonceChronoDetailService', () => {
    const spyDecorator = jasmine.createSpyObj('UrlDecoratorService', {
        urlAPIDecorate: '/test/url',
        generateParameters: null /* set test params to return here /*
    };
    const spyFetcher = jasmine.createSpyObj('APIFetcherService', {
        fetchJson: {}
    };
    let service: AnnonceChronoDetailService;
    ...

现在更改您的 providers 数组以使用 spies 而不是原始服务:

Now change your providers array to use the spies instead of the original services:

        providers: [
            AnnonceChronoDetailService,
            { provide: UrlDecoratorService, useValue: spyDecorator } ,
            { provide: APIFetcherService, useValue: spyFetcher },
            ]

然后在你的规范文件中你可以检查那些间谍.将这些建议更改为您真正关心的内容:

and then in your spec files you can check those spies. Change these suggestions to something you actually care about:

it('#fetchData should return value from observable', () => {
    spyFetcher.fetchJson.and.returnValue(of('observable value'));
    service.fetchData(alChrono).subscribe(value => {
        expect(value).toEqual('observable value');
    });
    expect(spyDecorator.urlAPIDecorate).toHaveBeenCalled();
    expect(spyDecorator.generateParameters).toHaveBeenCalledTimes(1);
    expect(spyFetcher.fetchJson).toHaveBeenCalledWith('/test/url', /* test params defined above */);
});

这篇关于类型错误:无法读取未定义的 jasmine-karma 的属性“fetchData"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆