NgOnInit и MediaChange тестирование с Karma

Я пытаюсь протестировать код в методе ngOnInit. Код отслеживает изменение размера экрана, чтобы панель навигации уменьшилась до размера мобильного устройства или оставалась верхней панелью. Я пробовал его около недели и постоянно получаю множество разных ошибок при тестировании. Я пропустил некоторый код для comp.component.ts, поскольку другой код для этого не нужен. Я продолжаю получать subscribe is not a method или Can'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: (?, ?, ?, ?), которое, как мне кажется, связано с ошибкой подписки, упомянутой выше.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
247
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Некоторые наблюдения:

  • ObservableMedia из гибкого макета необходимо внедрить в ваш компонент, чтобы он работал. Подробнее здесь
  • Вы не предоставляете MediaChange или Subscription в исходном компоненте, поэтому нет необходимости и в TestBed.

В приведенном ниже стеке мне пришлось сделать несколько предположений. Сообщите мне, если что-то из этого не так, или просто обновите stackblitz:

  • В вашей спецификации вы импортировали CompComponent, но в comp.component.ts вы определили NavigationComponent. Из двух я решил использовать NavigationComponent.
  • navClick отсутствовал в вашем коде выше, поэтому я предположил, что это @Output из вашего компонента (поскольку вы указываете путь к нему).
  • navItems также отсутствовал в приведенном выше коде, но, поскольку вы его тестируете, я предположил, что это важно, и предположил, что это входные данные для вашего компонента (опять же, просто по тому, как вы его использовали).
  • Вы не включили свой шаблон, поэтому я очень просто издевался над ним.
  • toggle был вызван из 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: [
    { provide: ObservableMedia, useValue: mockFlex }
]

За подробностями обращайтесь к stackblitz. Как видите, тест теперь пройден.

Извините, я попытался переименовать несколько вещей и очистить свой код для публикации, но явно проделал ужасную работу, опубликовал ее в спешке, прежде чем я ушел ... урок научился не делать этого снова. Прости за это. Я покопаюсь в вашем материале и посмотрю, есть ли у меня еще вопросы, а какие нет. Спасибо за ответ, я очень признателен.

bemon 28.10.2018 00:27

это сработало как шарм и было очень полезно, я был смущен частью инъекции, так как в ней не было декоратора для Inject. Мне нужно еще кое-что почитать по Angular и тестированию. Большое спасибо за помощь!

bemon 28.10.2018 15:07

Другие вопросы по теме