如何在茉莉花测试中模拟ActivatedRoute

时间:2018-03-17 18:31:58

标签: jasmine angular5

我试图模拟ActivatedRoute对象是一个模拟传递参数的测试。

然而,每次茉莉花测试运行时,我都会收到以下错误:

Error: Can't resolve all parameters for ActivatedRoute: (?, ?, ?, ?, ?, ?, ?, ?).
at syntaxError (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/esm5/compiler.js:485:22)
at CompileMetadataResolver.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.CompileMetadataResolver._getDependenciesMetadata (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/esm5/compiler.js:15700:1)
at CompileMetadataResolver.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.CompileMetadataResolver._getTypeMetadata (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/esm5/compiler.js:15535:1)
at CompileMetadataResolver.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.CompileMetadataResolver._getInjectableMetadata (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/esm5/compiler.js:15515:1)
at CompileMetadataResolver.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.CompileMetadataResolver.getProviderMetadata (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/esm5/compiler.js:15875:1)
at http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/esm5/compiler.js:15786:1
at Array.forEach (<anonymous>)
at CompileMetadataResolver.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.CompileMetadataResolver._getProvidersMetadata (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/esm5/compiler.js:15746:1)
at CompileMetadataResolver.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.CompileMetadataResolver.getNonNormalizedDirectiveMetadata (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/esm5/compiler.js:15007:1)
at CompileMetadataResolver.webpackJsonp../node_modules/@angular/compiler/esm5/compiler.js.CompileMetadataResolver._getEntryComponentMetadata (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/compiler/esm5/compiler.js:15848:26)

测试如下:

        import { TestBed } from '@angular/core/testing';

  import { ReviewComponent } from './review.component';
  import { ActivatedRoute, Router, Params } from '@angular/router';
  import {AppModule} from "../app.module";
  import { Observable } from 'rxjs/Observable';
  import 'rxjs/add/observable/of';

  class MockRouter {
    navigate = jasmine.createSpy('navigate');
  }

  class MockActivatedRoute extends ActivatedRoute {
      params: Observable<Params>;

      constructor(parameters?: { [key: string]: any; }) {
        super();
        this.params = Observable.of(parameters);
      }
    }

  describe('ReviewComponent', () => {
    let mockActivatedRoute: MockActivatedRoute;
    let mockRouter: MockRouter;

    beforeEach(() => {
      mockActivatedRoute = new MockActivatedRoute({'id': 1});
      mockRouter = new MockRouter();

      TestBed.configureTestingModule({
        declarations: [ReviewComponent],
        providers: [
          {provide: ActivatedRoute, useValue: mockActivatedRoute},
          {provide: Router, useValue: mockRouter}
        ],
        imports: [AppModule]
      }).compileComponents();
    });


    // beforeEach(async(() => {
    //
    //   TestBed.configureTestingModule({
    //     declarations: [ ReviewComponent ],
    //     providers: [{provide: ActivatedRoute, useValue: activeRoute},
    //                 {provide: Router, useValue: mockRouter}]
    //   })
    //   .compileComponents();
    // }));


    it('should create', () => {
      const fixture = TestBed.createComponent(ReviewComponent);
      fixture.detectChanges();
      const editComponent = fixture.debugElement.componentInstance;
      expect(editComponent).toBeTruthy();
    });

    // it('should have a review rating', () => {
    //   const compiled = fixture.debugElement;
    //   const title = compiled.query(By.css('.reviewRating'));
    //   expect(title).not.toBeNull();
    // });
    //
    // it('should have a review product name', () => {
    //   const compiled = fixture.debugElement;
    //   const productName = compiled.query(By.css('.review-title'));
    //   expect(productName).not.toBeNull()
    // });
    //
    // it('should have a header image', () => {
    //   const compiled = fixture.debugElement;
    //   const title = compiled.query(By.css('.reviewImageMain'));
    //   expect(title).not.toBeNull();
    // });


  });

我已经尝试过很多东西来模拟对象但是你可以从日志中看到,出于某种原因,TestBed没有使用模拟而是使用import。

有人可以帮忙吗?我今天已经失去了这么多小时来解决这个问题。

我差点忘了,组件看起来像这样:

import { Component, OnInit } from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {OnDestroy} from "@angular/core/src/metadata/lifecycle_hooks";


@Component({
  selector: 'app-review',
  templateUrl: './review.component.html',
  providers: [ActivatedRoute],
  styleUrls: ['./review.component.css']
})
export class ReviewComponent implements OnInit, OnDestroy {

  id: string;
  private sub: any;


  constructor(private route: ActivatedRoute, private router: Router){

  }

  cancel() {
    this.router.navigate(['/search']);
  }

  ngOnInit() {
    this.sub = this.route.params.subscribe(params => {
      this.id = params['id'];
    });
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }

}

1 个答案:

答案 0 :(得分:0)

知道了:)

哇,那不显眼。

审核我所包含的提供商中的ReviewComponent 提供者:[ActivatedRoute]

这导致异常发生,一旦我删除了这一行,测试开始通过。

失去了6个小时,但发现了错误:)。

    import { Component, OnInit } from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {OnDestroy} from "@angular/core/src/metadata/lifecycle_hooks";


@Component({
  selector: 'app-review',
  templateUrl: './review.component.html',
  providers: [],
  styleUrls: ['./review.component.css']
})
export class ReviewComponent implements OnInit, OnDestroy {

  id: string;
  private sub: any;


  constructor(private route: ActivatedRoute, private router: Router){

  }

  cancel() {
    this.router.navigate(['/search']);
  }

  ngOnInit() {
    this.sub = this.route.params.subscribe(params => {
      this.id = params['id'];
    });
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }

}