Error: Please call "TestBed.compileComponents" before your test

13,460

Solution 1

Template fetching is asynchronous when your templates are not inlined into your components, so you need to tell Jasmine that. Change

beforeEach(() => {
    TestBed.configureTestingModule({ ... })
        .compileComponents();
    fixture = TestBed.createComponent(MessagesComponent);
    comp = fixture.componentInstance;
});

to

beforeEach(async(() => {
    TestBed.configureTestingModule({ ... })
        .compileComponents()
        .then(() => {
            fixture = TestBed.createComponent(MessagesComponent);
            comp = fixture.componentInstance;
        });
}));

Solution 2

Since you are already using webpack, theoretically you should not have to call the compileComponents() function according to the official doc here, because webpack inlines templates and css as part of the automated build process that precedes running the test.

One possible reason that your template/css are not inlined is the IDE(VisualStudio/WebStorm/IntelliJ) auto compiles your ts to js and the webpack loaders which target for js/ts files are trying to get applied on the already compiled js files instead of the source ts files.

Share:
13,460
CommonSenseCode
Author by

CommonSenseCode

Software Skills: JavaScript NodeJS Golang React Redis Android Ionic/Cordova Framework XML, HTML, CSS, Sass, Less jQuery, Bootstrap MongoDB SQLite, Postgres & MySQL Git, Github, Bitbucket & Gitlab Linux Agile Development Unit Testing

Updated on June 09, 2022

Comments

  • CommonSenseCode
    CommonSenseCode about 2 years

    I'm getting this error:

    Error: This test module uses the component MessagesComponent which is using a "templateUrl", but they were never compiled. Please call "TestBed.compileComponents" before your test.

    When trying to run this simple test Angular 2 & Jasmine Test:

      let comp:    MessagesComponent;
    let fixture: ComponentFixture<MessagesComponent>;
    
    describe('MessagesComponent', () => {
        beforeEach(() => {
    
    
            TestBed.configureTestingModule({
                declarations: [ MessagesComponent ],
                providers:    [ {provide: DataService, useValue: {} } ]
    
            })
                .compileComponents(); // compile template and css
    
            fixture = TestBed.createComponent(MessagesComponent);
            comp = fixture.componentInstance;
    
        });
    
        it('example', () => {
            expect("true").toEqual("true");
        });
    });
    

    I think it might be due to something with my webpack test configuration:

    'use strict';
    
    const path = require('path');
    const webpack = require('webpack');
    
    module.exports = {
        devtool: 'inline-source-map',
        module: {
            loaders: [
                { loader: 'raw', test: /\.(css|html)$/ },
                { exclude: /node_modules/, loader: 'ts', test: /\.ts$/ }
            ]
        },
        resolve: {
            extensions: ['', '.js', '.ts'],
            modulesDirectories: ['node_modules'],
            root: path.resolve('.', 'src')
        },
        tslint: {
            emitErrors: true
        }
    };
    
  • CommonSenseCode
    CommonSenseCode over 7 years
    should I change the it(...) method in any way?
  • pe8ter
    pe8ter over 7 years
    Only if the it() does anything asynchronously, for example, if it fetches data from a service. It's totally okay if the the beforeEach() needs to be asynchronous but the it() does not.
  • CommonSenseCode
    CommonSenseCode over 7 years
    weird I asked because I keep gettin the same error message as posted in my original question but at least now it says 1 of 1 failed
  • pe8ter
    pe8ter over 7 years
    Oh, I missed something: ...compileComponents().then(() => { ... }) and create your component inside that function. You're creating the component before the template is loaded and compiled.
  • CommonSenseCode
    CommonSenseCode over 7 years
    please post the code complete how it should be I really don't understand
  • pe8ter
    pe8ter over 7 years
    On mobile. Will modify my answer tonight.
  • CommonSenseCode
    CommonSenseCode over 7 years
    please don't forget about this :)