1
votes

I have a fairly simple unit test file like so:

import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Http, HttpModule } from '@angular/http';
import { MockBackend } from '@angular/http/testing';
import { MaterialModule } from '@angular/material';
import { MediaChange, ObservableMedia } from "@angular/flex-layout";
import { PageHeaderComponent } from './page-header.component';
import { UserService } from '../user.service';
import { PreloadService } from '../preload.service';

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

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [PageHeaderComponent],
            providers: [
                {
                    provide: Http,
                    deps: [MockBackend]
                },
                PreloadService,
                UserService
            ],
            imports: [MaterialModule, ObservableMedia],
            schemas: [CUSTOM_ELEMENTS_SCHEMA]
        });

        fixture = TestBed.createComponent(PageHeaderComponent);
        component = fixture.componentInstance;
    });

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

It's testing a run-of-the-mill Angular CLI component that contains a subscription to watch breakpoints for element visibility:

constructor(public media: ObservableMedia) {
    // watch for changes in breakpoint
    media.asObservable()
        .subscribe((change: MediaChange) => {
            // update the header tooltip state
            if (change.mqAlias == 'xs') {
                this.showHeaderTooltip = false;
            }
            else {
                this.showHeaderTooltip = true;
            }
        });
}

ngOnInit() {
    // check breakpoint and set header tooltip state
    if (this.media.isActive('xs')) {
        this.showHeaderTooltip = false;
    } else {
        this.showHeaderTooltip = true;
    }
}

It throws this error:

Error: Unexpected value 'ObservableMedia' imported by the module 'DynamicTestModule'. Please add a @NgModule annotation. in http://localhost:9876/_karma_webpack_/polyfills.bundle.js (line 6972) ZoneAwareError@http://localhost:9876/_karma_webpack_/polyfills.bundle.js:6972:28 syntaxError@http://localhost:9876/_karma_webpack_/vendor.bundle.js:14803:39 http://localhost:9876/_karma_webpack_/vendor.bundle.js:28487:55 forEach@[native code]
....

I've seen similar error reports in my research, but not for ObservableMedia. I've tried adding the imports to app.module.ts, but that had no effect. What's missing?

1
if you have other node_modules in your sub-directories this could be the reason, for example in a local shared project that you might have used yarn link. This is due a versioning mismatch, run time get confused with relationships between tscongif moduleResolution and combinations of newer Node and Angular-cli installs. Cut the long story short delete the extra node_modules if you have anyUlug Toprak
@UlugToprak, thanks for the suggestion. I did refresh node_modules earlier.isherwood
By refreshing do you mean you ran npm install again? because thats not gonna solve the issue. I am guessing you have changed Angular or Node version recently. if you didn't i will let my self outUlug Toprak
I removed the node_modules directory and ran install, and there's only one directory. I don't use Yarn. Angular has been on 4.2.3 during the entire project. Node was updated at some point but doesn't seem to be related to this problem. Thanks again.isherwood

1 Answers

4
votes

I think you should use FlexLayoutModule instead of ObservableMedia because ObservableMedia is just base abstract class while you need to import angular module i.e class adorned with with @NgModule decorator

Docs