首页 > 解决方案 > 角度测试用例错误:无法读取未定义的属性 serviceUrl

问题描述

MyService.ts 文件 当我们从 secp 文件中调用服务时,serviceURl 变得未定义。

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
    export class Sendnotificationservice {
      constructor(private http: HttpClient) {} 
      public sendnotification(
        notificationModel: SendnotificationToModel
      ): Observable<any> {
        return this.http.post<any>(
          AppConfig.settings.serviceUrl +
            'api/Sendnotificationservice/sendnotification',
          notificationModel
          //AppConfig.setting.serviceUrl getting cannot read property serviceurl of undefined
        );
      }
    }

Myservice.spec.ts Frome 规范在这里我们调用服务时调用服务我们无法模拟 appconfig.ts 返回数据

import { Injectable, Injector, OnInit } from "@angular/core";
import { HttpClient, HttpResponce } from "@angular/common/http";
import { IAppConfig } from "./app-config.model";
    describe('Sendnotificationservice', () => {
      let service: Sendnotificationservice;
      let httpSpy: HttpTestingController;
      beforeEach(() => {
        TestBed.configureTestingModule({
          imports: [HttpclientTestingModule],
          providers: [Sendnotificationservice],
        });
        service = TestBed.get(Sendnotificationservice);
        service = TestBed.get(HttpTestingController);
      });
      it('it should get mail', () => {
        const test = {
          clientno: '',
          firstName: 'dev',
          lastName: 'som',
          phoneNo: '484758373',
        };
        service.sendnotification(test).subscribe((data) => {
          expect(data).toEqual(false);
        });
      });
    });

AppConfig.ts 无法模拟返回数据到服务测试用例文件

import { Injectable, Injector, OnInit } from "@angular/core";
import { HttpClient, HttpResponce } from "@angular/common/http";
import { IAppConfig } from "./app-config.model";
import { environment } from "src/environments/environment";
@Injectable()
export class AppConfig {
  static settings: iAppConfig;
  constructor(private http:HttpClient) {}
  load() {
    const jsonFile =
      window.location.hostname.toLowerCase().indexof("localhost") !== -1
        ? 'assets/config/config.local.json'
        : 'assets/config/config.${environment.name}.json';
      return new Promise<any>((resolve, reject) => {
        this.http
          .get(jsonFile)
          .toPromise()
          .them((response: Response) => {
            AppConfig.settings = <any>response;
            resolve();
          })
          .catch((response: any) => {
            reject(
              'could not load file '${jsonFile}': ${JSON.stringify(response)}
            );
          });
      });
    }
  }

标签: angularkarma-jasmineweb-frontendangular-testservicetestcase

解决方案


这不是你应该在单元测试中模拟的方式。现在你的应用程序代码中有测试代码,你也应该测试这个测试代码,如果你继续这样下去,你将进入一个无限循环,测试测试代码来测试测试代码。

最好也模拟该AppConfig服务:

import appConfig from 'assets/config/config.local.json';

class MockAppConfig {
  static settings: IAppConfig = appConfig as IAppConfig;
}

TestBed.configureTestingModule({
  imports: [HttpclientTestingModule],
  providers: [
    Sendnotificationservice, 
    { provide: AppConfig, useClass: MockAppConfig }
  ],
});

要完成这项工作,您可能必须"resolveJsonModule": truetsconfig.spec.json. .json考虑到您很可能不再提供此 JSON 文件,您也可以只导出一个对象而不是文件。这将通过代码提示保持内容类型安全。

尽管如此,您还没有到那里,因为您无法测试这样的Observable响应。你会得到一个错误,说你的“它没有期望”。有多种方法可以解决这个问题,一个简单的方法是 call done

it('it should get mail', (done) => {
  const test = {
    clientno: '',
    firstName: 'dev',
    lastName: 'som',
    phoneNo: '484758373',
   };

   service.sendnotification(test).subscribe((data) => {
     expect(data).toEqual(false);
     done(); // here
   });
});

不过,这对我来说仍然有点奇怪。您并没有真正测试服务对象,但您似乎正在测试 API 响应。该测试应该在调用 API 的后端完成,或者通过使用集成/e2e 测试来确保 API 正常工作


推荐阅读