Angular2 Unit Test Component getting "No Provider for DirectiveResolver"

2.3k views Asked by At

I'm getting the following error:

Error: No provider for DirectiveResolver!
Error: DI Exception
    at NoProviderError.BaseException [as constructor] (http://localhost:9876/jspm_packages/npm/[email protected]/src/facade/exceptions.js:19:23)
    at NoProviderError.AbstractProviderError [as constructor] (http://localhost:9876/jspm_packages/npm/[email protected]/src/core/di/reflective_exceptions.js:41:16)
    at new NoProviderError (http://localhost:9876/jspm_packages/npm/[email protected]/src/core/di/reflective_exceptions.js:77:16)
    at ReflectiveInjector_._throwOrNull (http://localhost:9876/jspm_packages/npm/[email protected]/src/core/di/reflective_injector.js:779:19)
    at ReflectiveInjector_._getByKeyDefault (http://localhost:9876/jspm_packages/npm/[email protected]/src/core/di/reflective_injector.js:807:25)
    at ReflectiveInjector_._getByKey (http://localhost:9876/jspm_packages/npm/[email protected]/src/core/di/reflective_injector.js:770:25)
    at ReflectiveInjector_.get (http://localhost:9876/jspm_packages/npm/[email protected]/src/core/di/reflective_injector.js:579:21)
    at TestComponentBuilder.createAsync (http://localhost:9876/jspm_packages/npm/[email protected]/src/testing/test_component_builder.js:185:52)
    at eval (http://localhost:9876/spec/campaignList.component.spec.js:53:20)
    at Object.eval (http://localhost:9876/jspm_packages/npm/[email protected]/src/testing/testing.js:113:13)

While trying to run this test that doesn't even have an expect (is crashing sooner that actually getting there):

import {
  it, iit, xit, describe, ddescribe, xdescribe, expect, beforeEach, inject,
  async, tick, withProviders, beforeEachProviders, TestComponentBuilder, fakeAsync
} from 'angular2/testing';

import { CampaignList } from 'components/campaign/campaignList.component'
import { CampaignService } from 'services/campaign.service'
import { provide } from 'angular2/core';

class MockCampaignService extends CampaignService {
    create() {
        return Promise.resolve(true);
    }
}

describe('CampaignList: component', () => {
    let tcb;

    beforeEachProviders(() => [
        TestComponentBuilder,
        provide(CampaignService, {useClass: MockCampaignService}),
        CampaignList
    ]);

    beforeEach(inject([TestComponentBuilder], _tcb => {
        tcb = _tcb
    }));

    it('should render `Hello World!`', done => {
        return tcb.createAsync(CampaignList).then(fixture => {
            fixture.detectChanges();
            var compiled = fixture.debugElement.nativeElement;
        })
        .catch(e => done.fail(e))
    })
})

And this is my karma.config.js:

/* global module */
module.exports = function (config) {
    'use strict';
    var glob = require("glob");
    var filesToServe = glob.sync("./app/**/*.@(js|ts|css|scss|html)");
    var specsToLoad = glob.sync("./spec/**/*.@(spec.js)").map(function(file){
      return file.substr(2);
    });
    config.set({
        autoWatch: true,
        singleRun: true,

        frameworks: ['jspm', 'jasmine'],

        files: [
            'node_modules/babel-polyfill/dist/polyfill.js',
            {pattern: 'node_modules/zone.js/dist/zone.js', included: true, watched: false},
            {pattern: 'node_modules/zone.js/dist/async-test.js', included: true, watched: false}
        ],

        jspm: {
            config: 'config.js',
            serveFiles: filesToServe,
            loadFiles: ['./base/test-setup.js'].concat(specsToLoad)
        },

        proxies: {
            '/spec/': '/base/spec/',
            '/app/': '/base/app/',
            '/jspm_packages/': '/base/jspm_packages/'
        },

        browsers: ['Chrome'],

        preprocessors: {
            'app/**/*.js': ['babel', 'sourcemap', 'coverage'],
            'spec/**/*.js': ['babel']
        },

        babelPreprocessor: {
            options: {
                sourceMap: 'inline'
            },
            sourceFileName: function(file) {
                return file.originalPath;
            }
        },

        reporters: ['coverage', 'progress'],

        coverageReporter: {
            instrumenters: {isparta: require('isparta')},
            instrumenter: {
                'app/*.js': 'isparta'
            },

            reporters: [
                {
                    type: 'text-summary',
                    subdir: normalizationBrowserName
                },
                {
                    type: 'html',
                    dir: 'coverage/',
                    subdir: normalizationBrowserName
                }
            ]
        }
    });

    function normalizationBrowserName(browser) {
        return browser.toLowerCase().split(/[ /-]/)[0];
    }
};

And this is my test-setup.js:

import {setBaseTestProviders} from 'angular2/testing';
import {
  TEST_BROWSER_PLATFORM_PROVIDERS,
  TEST_BROWSER_APPLICATION_PROVIDERS
} from 'angular2/platform/testing/browser';
setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS,
                     TEST_BROWSER_APPLICATION_PROVIDERS);

Does anyone have an idea why this is happening or what am I am supposed to do?

1

There are 1 answers

0
Bolza On BEST ANSWER

I figured it out: the test-setup.js was actually found but not transpiled by babel because it was in the root path whereas only files in app or spec were transpiled

    preprocessors: {
        'app/**/*.js': ['babel', 'sourcemap', 'coverage'],
        'spec/**/*.js': ['babel']
    },

So i just moved the test-setup inside the spec folder and changed the path to this

    jspm: {
        loadFiles: ['spec/test-setup.js'].concat(specsToLoad)
    }

And everything started working