【问题标题】:Error as Cannot read property 'subscribe' . for activated route in angular 7 while unit testing错误为无法读取属性“订阅”。单元测试时在角度 7 中激活路线
【发布时间】:2019-08-26 02:31:00
【问题描述】:

我收到错误,因为在单元测试时无法读取 Angular 7 中激活路由的未定义属性“订阅”。我已经以多种方式尝试过,请帮助。

Observer.of 不适合我,因为我有 rx.js 版本 6.3.3

这是我的组件文件 ChildComponent.ts

import { Component, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';

@Component({
    selector: 'app-child',
    template: `
        <h1>Enter your name</h1>
        <form
              [formGroup]="nameForm"
              (ngSubmit)="submitForm(nameForm)"
        >
            <input
                   type="text"
                   formControlName="firstName"
                   placeholder="first"
            >
            <input
                   type="text"
                   formControlName="lastName"
                   placeholder="last"
            >
            <button type="submit">launch to space</button>
        </form>
    `,
    styleUrls: ['./child.component.css']
})
export class ChildComponent {
    @Input() nameForm: FormGroup;
    private abc: number;
    constructor(
        public route: ActivatedRoute,
       ) {

        this.route.queryParams.subscribe(params => {
          this.abc = params['abc'];
        });

      }

    submitForm(form: FormGroup) {
        console.log(form);
        // really you would be using an event emitter
    }
}

这是我的子组件单元测试用例的单元测试文件


import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ReactiveFormsModule, FormBuilder } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { ActivatedRoute, Router, Data, Params } from '@angular/router';
import { Observable, of } from 'rxjs';
import { BehaviorSubject } from 'rxjs';


export class MockActivatedRoute {
    private paramsSubject = new BehaviorSubject(this.testParams);
    private _testParams: {};

    params  = this.paramsSubject.asObservable();

    get testParams() {
        return this._testParams;
    }
    set testParams(newParams: any) {
        this._testParams = newParams;
        this.paramsSubject.next(newParams);
    }
}


import { ChildComponent } from './child.component';


describe('StaticComponent', () => {
    let component: ChildComponent;
    let fixture: ComponentFixture<ChildComponent>;

    class MockActivatedRoute1 extends ActivatedRoute {
    constructor() {
        super();
        this.params = of({id: "5"});
    }
  }

    // create new instance of FormBuilder
    const formBuilder: FormBuilder = new FormBuilder();
    let activeRoute: MockActivatedRoute;  


    beforeEach(() => {
        activeRoute = new MockActivatedRoute();
    });


    beforeEach(
        async(() => {
            TestBed.configureTestingModule({
                declarations: [
                    ChildComponent
                ],
                imports: [
                    CommonModule,
                    ReactiveFormsModule,
                    //AppModule
                ],
                providers: [
                    // reference the new instance of formBuilder from above
                    { provide: FormBuilder, useValue: formBuilder },
                    {
                        provide: ActivatedRoute,
                        useValue: {
                            params: {
                                subscribe: (fn: (value: Data) => void) => fn({
                                    abc: 1
                                })
                            }
                        }
                    }
                ]
            }).compileComponents();
        })
    );

    beforeEach(() => {
        fixture = TestBed.createComponent(ChildComponent);
        component = fixture.componentInstance;

        // pass in the form dynamically
        component.nameForm = formBuilder.group({
            firstName: null,
            lastName: null
        });
        fixture.detectChanges();
    });

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

【问题讨论】:

    标签: angular typescript angular-unit-test angular-activatedroute


    【解决方案1】:

    你很亲密!为了让你的测试通过,我像这样模拟了 ActivatedRoute:

    const mockActivatedRoute = { 
      queryParams: of({ abc: 'testABC' }) 
    };
    

    然后在TestBed的providers数组中使用如下:

    providers: [
        ...
        { provide: ActivatedRoute, useValue: mockActivatedRoute }
    ]
    

    这是一个有效的Stackblitz。在 Stackblitz 中,我还注释掉了所有其他不再需要的代码。

    【讨论】:

      猜你喜欢
      • 2019-08-22
      • 2019-08-06
      • 1970-01-01
      • 1970-01-01
      • 2018-01-17
      • 2018-02-14
      • 1970-01-01
      • 1970-01-01
      • 2018-11-11
      相关资源
      最近更新 更多