【问题标题】:How to not import useless imports in angular component tests, when testing a component with a dependency?在测试具有依赖项的组件时,如何在角度组件测试中不导入无用的导入?
【发布时间】:2018-01-26 03:53:10
【问题描述】:

我无法弄清楚这段代码有什么问题。它一直告诉我没有 AlertService 的提供者。我提供了 AlertServiceSpy 类,但它仍然说没有提供 AlertService。一旦我将 CoreModule 和 RouterTestingModule 添加到导入中,它就会开始工作。

这一定是因为 AlertService 对它们有依赖关系,但是在这个测试中这完全不重要。我只是想测试 AlertComponent 并且不关心 AlertService 的依赖关系,因此我模拟了它。为什么我需要将 AlertService 的依赖项导入此测试?请帮忙!

describe('AlertComponent', () => {

  let comp: AlertComponent;
  let fixture: ComponentFixture<AlertComponent>;
  let de: DebugElement;
  let el: HTMLElement;
  let alertService: any;

  class AlertServiceSpy {

    getMessage = jasmine.createSpy('getMessage').and.callFake(
        () => Observable
            .create((observer) => {
                return 'message';
            })
    );

  }


  beforeEach(async(() => {

    TestBed.configureTestingModule({
      imports: [
      ],
      declarations: [        
        AlertComponent
      ],
      providers: [
        { provide: AlertService, useClass: AlertServiceSpy }
      ]

    }).overrideComponent(AlertComponent, {

      set: {
        providers: [
          { provide: AlertService, useClass: AlertServiceSpy }
        ]
      }

    }).compileComponents();

    fixture = TestBed.createComponent(AlertComponent);
    }));
  });

  // TESTS
  it('true is true', () => expect(true).toBe(true));

});

警报组件:

import { Component, OnInit } from '@angular/core';
import { AlertService } from '../Alert/alert.service';

@Component({
    moduleId:       module.id,
    selector:       'app-alert-system',
    templateUrl:    'alert.component.html',
})

export class AlertComponent implements OnInit {

    public message: any;

    constructor( private alertService: AlertService) {}

    ngOnInit() {
        this.alertService.getMessage().subscribe(
            message => { 
                this.message = message; 
            });
    }
}

警报服务:

import { Injectable } from '@angular/core';
import { Router, NavigationStart } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import { HttpAlertGenerator } from './http-alert-generator'

/*
    Service used for handling alerts.
*/
@Injectable()
export class AlertService {

    private _subject = new Subject<any>();
    private _keepAfterNavigationChange = false;
    private _httpAlertGenerator = new HttpAlertGenerator();

    constructor(private router: Router) {

        router.events.subscribe(event => {
            if (event instanceof NavigationStart) {
                if (this._keepAfterNavigationChange) {
                    this._keepAfterNavigationChange = false;
                } else {
                    this._subject.next();
                }
            }
        });

    }

    // public
    public httpAlert(errCode: number, 
                     additionalInfo: string,
                     keepAfterNavigationChange = true, 
                     displayDurationInMillis?: number) {

        const message = additionalInfo + ' ' + this._httpAlertGenerator.codeToMessage(errCode);

        if (errCode >= 300) {
            this.error(message, keepAfterNavigationChange);
        } else {
            this.success(message, keepAfterNavigationChange);
        }
    }

    public success(message: string, keepAfterNavigationChange = true, timeLimit = 5000) {
        this._keepAfterNavigationChange = keepAfterNavigationChange;
        this._subject.next({type: 'success', text: message});
        this.prepareNext(timeLimit);
    }

    public error(message: string, keepAfterNavigationChange = true) {
        this._keepAfterNavigationChange = keepAfterNavigationChange;
        this._subject.next({type: 'error', text: message});
    }

    // FOR ALERT COMPONENT
    public getMessage(): Observable<any> {
            return this._subject.asObservable();
    }

    private prepareNext(timelimit = 5000) {
        const nextSubj = this._subject;
        setTimeout(function(){
            nextSubj.next();
        }, timelimit);
    }
}

【问题讨论】:

  • 您是否在 app.module.ts 中将 AlertService 声明为提供程序?也在 let alertService: any;可以让 alertService: AlertService;
  • 我把它改成了alertService:AlertService。我在核心模块中提供它,我也将其导入 app.module

标签: angular typescript jasmine karma-runner


【解决方案1】:

我好像发现了问题,基本上和测试本身无关,有点奇怪。

问题是,在某个地方,我将文件夹名称从大写更改为小写。 Git 无法识别此更改并保留旧文件夹名称。

在我的 AlertComponent 中,我从 ../Alert/alert.service 导入了服务,而我仍在同一个文件夹中。我将其更改为 ./alert.service 并且神奇地开始工作。看来我得在文件夹的命名上更加小心了。

我从以下文章中得到了提示:

Angular 2 - No Provider error (even though I've added a provider)

【讨论】:

    猜你喜欢
    • 2019-08-02
    • 2022-10-06
    • 2019-03-23
    • 2019-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-20
    相关资源
    最近更新 更多