Угловой тест не проходит с впрыском MatDialog - PullRequest
0 голосов
/ 05 июля 2018

В настоящее время я создаю модульный тест для службы, которая открывает модалы с помощью MatDialog. Каждый тип модальных определяется в соответствующем файле компонента. Мне удалось без проблем создать модульные тесты для компонента, но сервисные тесты выдают следующую ошибку:

× should successfully create an alert popup with default config
  Chrome 67.0.3396 (Windows 10 0.0.0)
Failed: this.dialog.open is not a function
    at <Jasmine>
    at PopupService.alert (dist/dev/app/shared/ui/popup/popup.service.js:9:7503)
    at UserContext.eval (dist/dev/app/shared/ui/popup/popup.service.spec.js:19:26)
    at ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:388:26)
    at AsyncTestZoneSpec.onInvoke (node_modules/zone.js/dist/async-test.js:106:39)
    at ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/proxy.js:125:39)
    at ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:387:32)
    at Zone.runGuarded (node_modules/zone.js/dist/zone.js:151:47)
    at runInTestZone (node_modules/zone.js/dist/async-test.js:234:29)
    at UserContext.<anonymous> (node_modules/zone.js/dist/async-test.js:168:17)
    at ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:388:26)
    at ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/proxy.js:128:39)
    at ZoneDelegate.invoke (node_modules/zone.js/dist/zone.js:387:32)
    at Zone.run (node_modules/zone.js/dist/zone.js:138:43)
    at runInTestZone (node_modules/zone.js/dist/jasmine-patch.js:142:34)
    at UserContext.<anonymous> (node_modules/zone.js/dist/jasmine-patch.js:158:20)
    at <Jasmine>
    at ZoneDelegate.invokeTask (node_modules/zone.js/dist/zone.js:421:31)
    at Zone.runTask (node_modules/zone.js/dist/zone.js:188:47)
    at drainMicroTaskQueue (node_modules/zone.js/dist/zone.js:595:35)

Сами тесты выполняются, но эта ошибка выдается, как только вызывается MatDialog.open () (в сервисе). Эта ошибка не выдается при запуске приложения в разработке.

Вот фрагменты кода, относящиеся к вопросу:

Тестовый набор для службы:

import { inject, TestBed, async } from "@angular/core/testing";
import { PopupService } from "./popup.service";
import { MatDialogModule, MatDialog } from "@angular/material";
import { Injectable } from "@angular/core";
import { PopupAlertComponent } from './popup.component';

export function main() {

    describe('Service: PopupService', () => {

        let dialog: MatDialog,
                popupService: PopupService;

        beforeEach(() => {
            TestBed.configureTestingModule({
                providers: [
                    { provide: MatDialog, useValue: {} } //This is a workaround: otherwise a NullInjectorError is thrown
                ]
            });

            dialog = TestBed.get(MatDialog);
            popupService = new PopupService(dialog);

        });

        /*********************
         * CONFIRM           *
         ********************/
        it('should successfully create an confirm popup with default config',
            async(() => {
                popupService.confirm("test", "this is a test", "Ok", "Cancel");
            }));

        it('should successfully create an confirm popup with custom config',
            async(() => {
                let config = { disableClose: false, width: '850px' };
                popupService.confirm("test", "this is a test", "Ok", "Cancel", config);
            }));
    });
}

Модальные услуги:

    import { Injectable } from "@angular/core";
    import { MatDialog, MatDialogRef } from "@angular/material";
    import {
        PopupAlertComponent, PopupConfirmComponent, PopupInputComponent,
        PopupBillerListComponent, PopupListComponent
    } from "./popup.component";

    export class KeyValuePair {
        id: number;
        name: string;
    }

    export class ListObject {
        id: number;
        name: string;
        imageUrl: string;
    }

    /**
     * Class used to generate popups through the app, by calling one of the functions. (alert, input, confirm..)
     */
    @Injectable()
    export class PopupService {

        /*
        Base config for popups, passed in through mdDialog config options.
        Can be temporarily modified on a specific popup, if necessary.
         */
        config = {
            disableClose: true,
            width: '330px'
        };

        constructor(public dialog: MatDialog) {

        }

        /**
         * Base popup function that sets the popup text to specified strings, or allow the default values specified in the popup.component.
         * @param popupRef
         * @param {boolean} hasButtons
         * @param {string} title
         * @param {string} message
         * @param {string} okText
         * @param {string} cancelText
         * @returns {Observable<any>}
         */
        popup(popupRef: any, hasButtons: boolean, title: string, message: string, okText: string, cancelText: string) {
            if (title !== "")
                popupRef.componentInstance.title = title;
            if (message !== "")
                popupRef.componentInstance.message = message;
            if (hasButtons) {
                if (okText !== "")
                    popupRef.componentInstance.okText = okText;
                if (cancelText !== "")
                    popupRef.componentInstance.cancelText = cancelText;
            }

            return popupRef.afterClosed();
        }

        /**
         * Input popup function with input popup specific features
         * @param {string} title
         * @param {string} message
         * @param {string} okText
         * @param {string} cancelText
         * @param {object} config (optional)
         * @returns {Observable<any>}
         */
        input(title: string, message: string, okText: string, cancelText: string, config?: {}) {
            let popupRef: MatDialogRef<PopupInputComponent>;

            popupRef = this.dialog.open(PopupInputComponent, config ? config : this.config);

            return this.popup(popupRef, true, title, message, okText, cancelText);
        }
    }

Модальная составляющая:

import { Component } from "@angular/core";
import { MatDialogRef } from "@angular/material";
import { PopupService, KeyValuePair } from "./popup.service";

/**
 * Input Popup
 * Popup that will be used in cases where a single input popup is required
 */
@Component({
    moduleId : module.id,
    selector: 'tp-input-popup',
    template: `
        <div class="body">
            <mat-dialog-content>
                <h4><p class="text-center">{{title | translate}}</p></h4>
                <hr>
            </mat-dialog-content>
            <mat-dialog-actions align="end">
                <div class="group">
                    <input #input
                           id="input"
                           type="tel"
                           [ngClass]="input.validity.valid ? 'used' : false"
                           required>
                    <span class="highlight"></span>
                    <span class="bar"></span>
                    <label>{{message | translate}}</label>
                </div>
                <div class="button-position">
                    <button mat-button type="button" class="button" (click)="popup.close(false)">
                        <span><b>{{cancelText | translate}}</b></span>
                    </button>
                    <button mat-raised-button type="button" class="button" (click)="popup.close(input.value)">
                        <span><b>{{okText | translate}}</b></span>
                    </button>
                </div>
            </mat-dialog-actions>
        </div>
    `,
    styleUrls  : ['popup.component.css']
})
export class PopupInputComponent {
    title: string      = "Input";
    message: string    = "Enter your data here:";
    okText: string     = "Ok";
    cancelText: string = "Cancel";

    constructor(public popup: MatDialogRef<PopupInputComponent>) {
    }
}

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

Во время поисков я нашел другие вопросы, которые кажутся похожими, но ни один из них не касается этой конкретной ошибки в Карме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...