使用Karma进行onInit和MediaChange测试

问题描述 投票:1回答:1

我试图在ngOnInit方法中测试代码。该代码监视屏幕大小的变化,导航栏可以调整大小到移动设备或保持为顶部栏。我已经尝试了大约一个星期,并在测试时不断出现一系列不同的错误。我遗漏了comp.component.ts的一些代码,因为其他代码不是必需的。我一直得到subscribe is not a methodCan't resolve all parameters for MediaChange: (?, ?, ?, ?)。关于如何为这个或任何你可能建议查看的资源编写测试的任何建议,以帮助我解决这个问题。

comp.component.ts

import { Component, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { MediaChange, ObservableMedia } from '@angular/flex-layout';

@Component({
    selector: 'app-comp',
    templateUrl: './comp.component.html',
    styleUrls: ['./comp.component.scss']
})

export class NavigationComponent implements OnInit {
    isOpen: Boolean;
    watcher: Subscription;
    activeMediaQuery = "";
    media: ObservableMedia;

    constructor() {
        this.isOpen = false;
    }

    ngOnInit(): void {
        this.watcher = this.media.subscribe((change: MediaChange) => {
            this.activeMediaQuery = change ? `'${change.mqAlias}' = (${change.mediaQuery})` : '';
            this.isOpen = false;
        });
    }

    navPressed(event, path): void {
        this.navClick.emit(path);
        if ( this.checkSize() ) this.toggle();
    }

    checkSize(): Boolean {
        return this.activeMediaQuery.includes('xs') || this.activeMediaQuery.includes('sm');
    }
}

comp.component.spec.ts

import { Component } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { DebugElement } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatButtonModule, MatToolbarModule, MatIconModule } from '@angular/material';
import { CompComponent } from './comp.component';
import { Subscription } from 'rxjs';
import { MediaChange, ObservableMedia } from '@angular/flex-layout';


@Component({
    selector: 'app-test-component-wrapper',
    template: '<app-navigation [navItems]="clickables" (navClick)="handleNavClick($event)"></app-navigation>'
})

class TestWrapperComponent {
    clickables = [
        { path: '/login', label: 'Login', onClick() {} }
    ];
}

describe('app testing', () => {
    let component: CompComponent;
    let fixture: ComponentFixture<TestWrapperComponent>;

    beforeEach(async(() => {
        TestBed.configureTestingModule({
            imports: [
                MatButtonModule,
                MatToolbarModule,
                MatIconModule,
                BrowserAnimationsModule
            ],
            declarations: [
                TestWrapperComponent,
                NavigationComponent
            ],
            providers: [
                ObservableMedia,
                MediaChange,
                Subscription
            ]
        }).compileComponents();
        fixture = TestBed.createComponent(TestWrapperComponent);
    }));

    it('should create and have Login label', () => {
        // EDIT START
        spyOn(ObservableMedia, 'prototype');
        // EDIT END
        expect(fixture).toBeTruthy();
        fixture.detectChanges();
        fixture.whenStable().then(() => {
            component = fixture.debugElement.children[0].componentInstance;
            expect(component.navItems[0].label).toBe('Login');
        });
    });
});

编辑:使用我添加的代码在代码中添加了“编辑”注释。我现在得到resolve all parameters for MediaChange: (?, ?, ?, ?)错误,我认为是从上面提到的订阅错误向前进展。

javascript angular typescript jasmine karma-jasmine
1个回答
1
投票

一些观察:

  • 需要将flex-layout中的ObservableMedia注入到组件中才能工作。详情here
  • 您没有在原始组件中提供MediaChange或Subscription,因此也不需要在TestBed中。

在下面的stackblitz中,我不得不做一些假设。如果其中任何一个出错,请告诉我,或者继续更新stackblitz:

  • 在您的规范中导入了CompComponent,但在comp.component.ts中定义了NavigationComponent。在我选择使用NavigationComponent的两个中。
  • 上面的代码中缺少navClick,所以我认为它是来自组件的@Output(因为你发出了一个路径)。
  • 上面的代码中也缺少navItems,但是由于你正在测试它,我认为这很重要,并且猜测它是你组件的输入(再次,就像你使用它的方式一样)。
  • 你没有包含你的模板,所以我非常简单地嘲笑它。
  • 切换是从navPressed中调用的,但是不存在所以我将其创建为空函数。

这是stackblitz:https://stackblitz.com/edit/stackoverflow-q-53024049?file=app%2Fmy.component.spec.ts

为了解决你的问题:我进行了上述更改,并使用以下方法模拟传入的ObservableMedia对象:

let mockFlex = jasmine.createSpyObj({
  subscribe: ({mqAlias: 'xs', mediaQuery: ''}),
  isActive: true,
  });

我还将providers数组更改为以下内容:

providers: [
    { provide: ObservableMedia, useValue: mockFlex }
]

查看stackblitz了解所有细节。正如你在那里看到的那样,测试现在已经过去了。

© www.soinside.com 2019 - 2024. All rights reserved.