Угловой модульный тест возвращает «не может прочитать свойство неопределенного» для Http Post - PullRequest
0 голосов
/ 02 декабря 2018

У меня есть служба, в которой мои точки отдыха определяются в конструкторе, поэтому я настроил их как переменные.Когда я запускаю свои модульные тесты, эти свойства возвращаются как неопределенные.Я относительно новичок в модульном тестировании, поэтому я не уверен, что пропустил очевидный шаг ...

Вот мой service.ts:

import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class PulldownService {

  public pulldownData: any = [];
  public restURL;

  constructor(public http: HttpClient, public router: Router) {
    this.getEnvConf().subscribe(
        res => {
          this.restURL = res[window.location.hostname];
        }
    );
  }

  getEnvConf(): Observable<any> {
    return this.http.get('./assets/data/environment-config.json');
  }
  postClaim() {
    let headerTarget;
    if (this.restURL['target_env']) {
      headerTarget = {'Accept': 'application/json', 'Content-Type': 'application/json', 'target_env': this.restURL['targetEnv']};
    } else {
      headerTarget = {'Accept': 'application/json', 'Content-Type': 'application/json'};
    }
    const httpHeaders = new HttpHeaders(headerTarget);
    const options = { headers: httpHeaders };
    return this.http.post( this.restURL['restEndPoint'],
      { 'names' : [
        'PersonRelationType',
        'State',
        ...
        ...

      ]}, options ).subscribe(
      data => {
        // Success!
        this.pulldownData.push(data);
      }
      ,
      (err: HttpErrorResponse) => {
        if (err.error instanceof Error) {
          // A client-side or network error occurred.
          this.router.navigateByUrl('/error');
          console.log('An error occurred:', err.error.message);
        } else {
          // The backend returned an unsuccessful response code.
          this.router.navigateByUrl('/error');
          console.log(`Backend returned code ${err.status}, body was: ${err.error}`);
        }
      },
      () => {
        this.router.navigateByUrl('/getstart');
      }
    );
  }
}

Вот мой service.spec.ts

import { PulldownService } from './pulldown.service';
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { HttpRequest } from '@angular/common/http';

describe('PulldownService', () => {
  let service: PulldownService;
  let httpTestingController: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [ HttpClientTestingModule, RouterTestingModule ],
      providers: [ PulldownService ]
    });
    httpTestingController = TestBed.get(HttpTestingController);
    service = TestBed.get(PulldownService);
  });
  describe('getEnvConfig', () => {
    it('should call get with the correct url', () => {
      // no subscribe method called in getEnvConfig
      // service.getEnvConf().subscribe();
      const req = httpTestingController.expectOne('./assets/data/environment-config.json');
      req.flush({ 'restEndPoint': 'http://localhost:8080/typelist?version=1', 'target_env': null});
      httpTestingController.verify();
      // expect(req.request.url.endsWith('environment-config.json')).toEqual(true);
    });
  });
  describe('postClaim', () => {

    it('should be called with proper arguments', () => {
      const responseForm = '<form />';
      const pulldownService = TestBed.get(PulldownService);
      const http = TestBed.get(HttpTestingController);
      let postResponse;

      pulldownService.postClaim().subscribe((response) => {
        postResponse = response;
      });
      http.expectOne((request: HttpRequest<any>) => {
        return request.method === 'POST'
          && request.url === 'http://localhost:8080/typelist?version=1'
          && JSON.stringify(request.body) === JSON.stringify({
            names: ['State']
          })
          && request.headers.get('Accept') === 'application/json'
          && request.headers.get('Content-Type') === 'application/json'
          && request.headers.get('target_env') === null;
      }).flush(responseForm);
      expect(postResponse).toEqual(responseForm);
    });
  });
})

Ошибка, которую я продолжаю получать: TypeError: Невозможно прочитать свойство 'target_env' из неопределенного.После удаления «target_env» из моей функции, я вижу новую, другую ошибку для «restEndPoint».

Любая помощь по этому вопросу будет принята с благодарностью.Спасибо

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018

Ошибки для target_env и restEndPoint вызваны тем, что this.restURL не определено.В вашем первом модульном тесте вы правильно смоделировали вызов, но вы должны вернуть { 'localhost' : { 'restEndPoint': 'http://localhost:8080/typelist?version=1', 'target_env': null } }, потому что в конструкторе PulldownService вы устанавливаете this.restURL = res[window.location.hostname] (вместо this.restURL = res).Во втором модульном тесте вы вообще не высмеивали начальный результат.

Поскольку все ваши модульные тесты, вероятно, будут нуждаться в такой обработке, я бы предложил перенести этот смоделированный вызов в beforeEach(),после service = TestBed.get(PulldownService);

Примечание: вам не нужно снова определять pulldownService и http во втором тесте, поскольку у вас уже есть httpTestingController и service.

0 голосов
/ 02 декабря 2018

Ваш метод postClaim() должен быть определен restURL.restURL определяется только в том случае, если служба получила ответ на запрос, который она отправила в конструкторе.

Но во втором модульном тесте вы никогда не скажете контроллеру http, чтобы он сбрасывал ответ на этот первый запрос.перед звонком postClaim().Таким образом, restURL не определено, поэтому возникает ошибка.

Даже если вы исправите свой тест, у вашего сервиса будет условие состязания: при раннем вызове метод postClaim () будет иметь ту же ошибку, что и в вашем тесте,Почему бы вам не использовать поддержку среды CLI для определения статических, заранее известных параметров конфигурации?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...