RouterTestingModule не предоставляет провайдера для Location - PullRequest
0 голосов
/ 17 декабря 2018

Я тестирую модуль Component, в котором используются два других компонента.Другие компоненты создаются при нажатии кнопки

.html

    <div id="homepage-top-div" class="homepage-component-css-grid-container">  ...
        <button id="get-question-list-button" [routerLink]="questionListRouterLink" class="btn content-div__button--blue css-grid-item-button-div btn-sm">See Questions</button>
      </div>
      <div id="practice-component-top-div" class="css-grid-container-div common-styles-div--white"> <!-- 4 rows, 1 column-->
...
        <button id="new-question-button" [routerLink]="newQuestionRouterLink"  class="btn content-div__button--blue css-grid-item-button-div btn-sm">Create a Question</button>
      </div>
    </div>

.ts

export class HomepageContentComponentComponent implements OnInit {

  public questionListRouterLink="/practice-question-list";
  public newQuestionRouterLink="/new-practice-question";


  constructor() {

  }

  ngOnInit() {
  }

}

Я создал спецификацию, но при запуске я получаю следующую ошибкуэто - Error: StaticInjectorError[Location]: NullInjectorError: No provider for Location!

Спецификация

import {async, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
import { HomepageContentComponentComponent } from './homepage-content-component.component';
import {RouterTestingModule} from "@angular/router/testing";
import {AppRoutingModule} from "../app-routing.module";
import {Router} from "@angular/router";
import {routes} from '../app-routing.module';
import {NewPracticeQuestionComponent} from "../new-practice-question/new-practice-question.component";
import {PraticeQuestionListComponent} from "../pratice-question-list/pratice-question-list.component";
import {NgModule} from "@angular/core";
import {AppModule} from "../app.module";

fdescribe('HomepageContentComponentComponent', () => {
  let component: HomepageContentComponentComponent;
  let fixture: ComponentFixture<HomepageContentComponentComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports:[
        AppModule,
        AppRoutingModule,
        RouterTestingModule.withRoutes(routes) //<-- I SUPPOSE THIS STEP SHOULD PROVIDE ROUTERTESTINGMODULE WITH PROVIDERS FOR LOCATION BUT IT SEEMS IT ISN'T
      ],
      declarations: [ HomepageContentComponentComponent,
                  NewPracticeQuestionComponent,
        PraticeQuestionListComponent]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(HomepageContentComponentComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should navigate to New Questions Component when New Question button is clicked',fakeAsync(()=>{
    let router:Router;
    let location:Location;
    router = TestBed.get(Router);
    location = TestBed.get(Location);
    console.log('initial router is ',router);
    console.log('initial location is ',location);
    router.initialNavigation();
    router.navigate(['new-practice-question']);
    tick();
    console.log('new router is ',router);
    console.log('new location is ',location);

    expect(location.pathname).toBe('/new-practice-question');
  }));
});

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

Причина, по которой было выбрано неправильное местоположение и почему import {Location} from "@angular/common"; помогла, заключается в том, что, не импортируя его, TypeScript фактически думает, что вы хотите использовать тип window.location, который совершенно отличается от того, который вы ищете,

Поскольку тип является токеном для извлечения нужного экземпляра из реестра DI angular, вы ничего не получите, если используете неправильный тип.Когда вы закомментируете импорт и «щелкнете» по типу Location в вашей IDE, вы увидите, что выбранный тип на самом деле является интерфейсом DOM, а не реализацией Angular.Этот интерфейс DOM неявно присутствует, когда в вашем tsconfig.json есть "lib": ["dom"].

Импорт Location из angular явно затмевает Location из DOM, выбирается правильный тип, и в реестре DI angular находится правильный Location экземпляр.

На самом деле это довольно легкоошибку (я сделал это сам), потому что даже если вы забудете импортировать Location, будет выбран DOM Location, и вы вообще не получите никакой обратной связи в вашей IDE, и вам будет интересно, почему DI не работает.

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

Раньше я заставлял код работать, явно добавляя провайдеров.Но я считаю, что это не должно быть так.Я не был уверен, почему только использование RouterTestingModule не сработало.

Обходной путь

providers:[...,
{provide: Location, useClass: SpyLocation},
        {provide: LocationStrategy, useClass: MockLocationStrategy},
        {provide: NgModuleFactoryLoader, useClass: SpyNgModuleFactoryLoader}]

Фактическая проблема заключалась в том, что по неизвестной причине было выбрано неправильное определение Location,Тест работал без явного добавления providers, когда я добавил import {Location} from "@angular/common";

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