为什么我会收到“失败:无法读取未定义的属性'subscribe'"?在运行测试时? [英] Why am I getting a "Failed: Cannot read property 'subscribe' of undefined" while running tests?

查看:183
本文介绍了为什么我会收到“失败:无法读取未定义的属性'subscribe'"?在运行测试时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Angular2 +中的测试还比较陌生,并且正在设置我的文件进行测试.自构建项目以来,我已经编写了很多代码,现在正尝试测试其中的一部分.但是,现在这些测试中有很多已经坏掉了,因此我现在尝试删除不需要的默认测试或修复有用的测试.

I am relatively new to testing in Angular2+ and am setting up my files for testing. Since building the project, I've written a lot of code and am now trying to test parts of it. However, lots of those tests are now broken so I am now trying to delete the unneeded default tests or fix the ones that are useful.

该特定测试无法运行,因为它在命中It()测试方法之前失败了.我不确定我缺少什么,任何帮助将不胜感激.

This particular test won't run because it fails before it hits the It() testing method. I'm not sure what I'm missing, any help would be appreciated.

我收到此错误:

Failed: Cannot read property 'subscribe' of undefined
TypeError: Cannot read property 'subscribe' of undefined
    at AppComponent../src/app/app.component.ts.AppComponent.setupLanguageTranslation (src/app/app.component.ts:48:26)
    at AppComponent../src/app/app.component.ts.AppComponent.ngOnInit (src/app/app.component.ts:32:14)
    at checkAndUpdateDirectiveInline (node_modules/@angular/core/fesm5/core.js:22089:1)
    at checkAndUpdateNodeInline (node_modules/@angular/core/fesm5/core.js:23353:1)
    at checkAndUpdateNode (node_modules/@angular/core/fesm5/core.js:23315:1)
    at debugCheckAndUpdateNode (node_modules/@angular/core/fesm5/core.js:23949:1)
    at debugCheckDirectivesFn (node_modules/@angular/core/fesm5/core.js:23909:1)
    at Object.eval [as updateDirectives] (ng:///DynamicTestModule/AppComponent_Host.ngfactory.js:9:9)
    at Object.debugUpdateDirectives [as updateDirectives] (node_modules/@angular/core/fesm5/core.js:23901:1)
    at checkAndUpdateView (node_modules/@angular/core/fesm5/core.js:23297:1)

我已经尝试了许多类似问题的文章,包括但不限于:

I've tried a variety of articles with similar issues including, but not limited to:

  • Cannot read property 'subscribe' of undefined after running npm test (Angular 2 unit testing)
  • https://www.reddit.com/r/Angular2/comments/87w8su/what_am_im_doing_wrong_with_observables_and/
  • karma TypeError "Cannot read property 'subscribe' of undefined"

App.component.ts

App.component.ts

export class AppComponent implements OnInit, OnDestroy {
    title = 'planox';
    showError = false;
    errorMessage = '';
    translatedText: string;

    constructor(private _translate: TranslateService,
                private utils: Utils) {}

    ngOnInit(): void {
        this.setupLanguageTranslation();
    }

    ngOnDestroy(): void {
        this._translate.onLangChanged.unsubscribe();
    }

    setupLanguageTranslation() {
        this.subscribeToLangChanged();
        // set language
        this._translate.setDefaultLang('en'); // set English as default
        this._translate.enableFallback(true); // enable fallback

        // set current language
        this.selectLang('en');

        this.utils.error.subscribe(response => {
            this.errorMessage = response;
            this.showError = true;
            setTimeout( () => {
                this.showError = false;
            }, 2000);
        });
    }

    selectLang(lang: string) {
        // set default;
        this._translate.use(lang);
    }

    subscribeToLangChanged() {
        // refresh text
        this.refreshText();
        return this._translate.onLangChanged.value;
    }

    refreshText() {
        // refresh translation when language change
        this.translatedText = this._translate.instant('hello world');
    }

}

app.component.spec.ts

app.component.spec.ts

import {TestBed, async, ComponentFixture, inject} from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component';
import {TranslateService} from './translate/translate.service';
import Utils from './shared/utils';
import {MockTranslateService} from './mocks/mockTranslateService';
import {MockUtils} from './mocks/mockUtils';
import {TRANSLATIONS} from './translate/translation';


describe('AppComponent', () => {
    let fixture: ComponentFixture<AppComponent>;

    beforeEach(async(() => {
        const mockTranslate = new MockTranslateService(TRANSLATIONS);
        TestBed.configureTestingModule({
            imports: [
                RouterTestingModule
            ],
            declarations: [
                AppComponent
            ],
            providers: [
                {provide: TranslateService, useValue: mockTranslate},
                {provide: Utils, useValue: MockUtils},
            ]
        });

        fixture = TestBed.createComponent(AppComponent);
        fixture.detectChanges();
    }));

    it('should create the app', () => {
        fixture = TestBed.createComponent(AppComponent);
        const app = fixture.debugElement.componentInstance;
        expect(app).toBeTruthy();
    });
});

Utils.ts:

import {Subject, throwError} from 'rxjs';
import {Injectable} from '@angular/core';
import {Router} from '@angular/router';
import {Role} from '../classes/role/role.enum';

export enum KEY_CODE {
    ENTER = 13,
    RIGHT_ARROW = 39,
    LEFT_ARROW = 37
}

@Injectable({
    providedIn: 'root'
})
export default class Utils {
    error: Subject<string> = new Subject<string>();

    constructor(private router: Router) {}

    handleError(service: string, error: Response | any, customMessage?: string) {
        const err = service + '::handleError' + '=  ' + error;
        this.error.next(customMessage);
        return throwError(error);
    }

    encodeBase64(value: any) {
        return btoa(JSON.stringify(value));
    }

    decodeBase64(value: any) {
        return atob(value);
    }

    navigateToDefaultPage(usersRole: Role) {
        if (usersRole === Role.Employee) {
            this.router.navigate(['/dashboardNavigation', {outlets: {dashNav: ['productionDashboard']}}]);
        } else if (usersRole === Role.Client) {
            this.router.navigate(['/clientDashboard']);
        } else if (usersRole === Role.OfficeAdmin) {
            this.router.navigate(['/dashboardNavigation', {outlets: {dashNav: ['enterpriseDashboard']}}]);
        } else {
            this.router.navigate(['/auth']);
        }
    }

    validateEmail(inputText: string) {
        const mailFormat = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
        if (inputText.match(mailFormat)) {
            return true;
        } else {
            return false;
        }
    }
}

mockUtils.ts

mockUtils.ts

import Utils from "../shared/utils";
import {Subject} from "rxjs";

export class MockUtils extends Utils {
    error = new Subject<string>();
}

基本上,我需要帮助来设置测试页面的结构,以便我可以开始编写有用的测试.

Basically I need help setting up the structure of the testing page so that I can start writing useful tests.

我不确定您需要什么,我可以提供您可能需要帮助的任何其他代码.

I can provide any additional code you may need to help, wasn't sure what all would be needed for this.

推荐答案

从beforeEach方法中删除 fixture.detectChanges(),将其从其中删除,并在需要时将其移至每个测试中对您来说,我认为这是一个错误,在Angular 6和Angular 7上看到过

delete fixture.detectChanges() from the beforeEach method, remove it from there, and moving it into each test if needed will fix it for you, i think it's a bug, seen it on Angular 6 and Angular 7

因此您的beforeEach将更改为:

so your beforeEach will change to:

beforeEach(async(() => {
    const mockTranslate = new MockTranslateService(TRANSLATIONS);
    TestBed.configureTestingModule({
        imports: [
            RouterTestingModule
        ],
        declarations: [
            AppComponent
        ],
        providers: [
            {provide: TranslateService, useValue: mockTranslate},
            {provide: Utils, useValue: MockUtils},
        ]
    });

    fixture = TestBed.createComponent(AppComponent);
    // detection deleted here
}));

这篇关于为什么我会收到“失败:无法读取未定义的属性'subscribe'"?在运行测试时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆