dimanche 2 octobre 2016

Angular2 Service Unit Test Fails with TypeError: undefined is not an object

I am testing my authService. This is the full Test, yet Karma tells me, authService is undefined. I have plenty of Service which AuthService depends upon, but I provided and injected them all properly.

authservice.spec.ts

import { provide } from "@angular/core";
import { AuthHttp } from "angular2-jwt";
import { HTTP_PROVIDERS, XHRBackend } from "@angular/http";
import { MockBackend } from "@angular/http/testing";
import {
    TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
    TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS
} from "@angular/platform-browser-dynamic/testing";
import {
    beforeEachProviders,
    inject,
    beforeEach,
    it,
    describe,
    setBaseTestProviders
} from "@angular/core/testing";
import { Subject } from "rxjs/Subject";
import { AuthService } from "./auth.service";
import { BackendService } from "../../backend/backend.service";
import { ErrorService } from "../../error/error.service";
import { LoggerService } from "../../logger/logger.service";
import { NavService } from "../../nav/nav-service/nav.service";
import { Store } from "@ngrx/store";
import { TestComponentBuilder } from "@angular/compiler/testing";
import { ToastController, AlertController } from "ionic-angular";
setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);

describe("AuthService", () => {

    let response = new Subject();
    let tcb;
    let authService;
    let navService;
    let backendService;
    let errorService;
    let store;
    let loggerService;

    class StubErrorService extends ErrorService {
        constructor() {
            super(null, null);
        }

        toast(title) {
            console.error(title);
        }

        modal(title, subtitle) {
            console.error(title, subtitle);
        }
    }

    class StubBackendService extends BackendService {

    }

    class StubStore extends Store<any> {

    }

    class StubLoggerService extends LoggerService {

    }

    class StubNavService extends NavService {

    }

    // PROVIDE

    beforeEachProviders(() => [
        HTTP_PROVIDERS,
        provide(AuthHttp, {
            useValue: {
                get: (url: string) => {
                    return response;
                }
            }
        }),
        AuthService,
        TestComponentBuilder,
        provide(ToastController, {useClass: null}),
        provide(AlertController, {useClass: null}),
        provide(ErrorService, {useClass: StubErrorService}),
        provide(XHRBackend, {useClass: MockBackend}),
        provide(BackendService, {useClass: StubBackendService}),
        provide(Store, {useClass: StubStore}),
        provide(LoggerService, {useClass: StubLoggerService}),
        provide(NavService, {useClass: StubNavService})
    ]);

    // INJECTS

    beforeEach(inject([TestComponentBuilder, AuthService, ErrorService, BackendService, Store, LoggerService, NavService], (_tcb, as, es, bs, s, ls, ns) => {
        tcb = _tcb;
        authService = as;
        navService = ns;
        errorService = es;
        store = s;
        backendService = bs;
        loggerService = ls;
    }));

    it("should test authservice", () => {
        authService.logout();
    });
});

Console

username@MBP ~/d/project> gulp test
[18:43:59] Using gulpfile ~/devel/project/gulpfile.js
[18:43:59] Starting 'clean'...
[18:43:59] Finished 'clean' after 23 ms
[18:43:59] Starting 'test'...
[18:43:59] Starting 'sass'...
[18:43:59] Starting 'html'...
[18:43:59] Starting 'fonts'...
[18:43:59] Starting 'scripts'...
[18:43:59] Finished 'scripts' after 66 ms
[18:43:59] Finished 'fonts' after 69 ms
[18:43:59] Finished 'html' after 93 ms
[18:44:00] Finished 'sass' after 1.06 s
PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 1 of 2 SUCCESS (0 secs / 0.002 secs)
02 10 2016 18:44:27.571:ERROR [PhantomJS 2.1.1 (Mac OS X 0.0.0) | AuthService | should test authservice]: _instantiateProvider@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31186:37
_new@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31175:41
getObjByKeyId@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:30827:54
_getByKeyDefault@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31355:51
_getByKey@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31327:41
_getByReflectiveDependency@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31317:30
_instantiate@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31216:62
_instantiateProvider@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31186:37
_new@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31175:41
getObjByKeyId@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:30827:54
_getByKeyDefault@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31355:51
_getByKey@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31327:41
_getByReflectiveDependency@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31317:30
_instantiate@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31214:62
_instantiateProvider@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31186:37
_new@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31175:41
getObjByKeyId@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:30827:54
_getByKeyDefault@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31355:51
_getByKey@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31327:41
get@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31136:30
http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:39626:74
map@[native code]
apply@[native code]
call@[native code]
call@[native code]
map@http://localhost:9876/base/node_modules/es6-shim/es6-shim.js?a6f182025471e814687938cc88dbe6958e6e40da:289:20
execute@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:39626:32
http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:39720:62
_instantiate@http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb:31312:97
02 10 2016 18:44:27.572:ERROR [PhantomJS 2.1.1 (Mac OS X 0.0.0) | AuthService | should test authservice]: TypeError: undefined is not an object (evaluating 'authService.logout') in http://localhost:9876/absolute/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify?f9285465bd1c331fbe769b96bd252004b54605fb (line 891)
PhantomJS 2.1.1 (Mac OS X 0.0.0) AuthService should test authservice FAILED
    _instantiateProvider@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31186:37 <- node_modules/@angular/core/src/di/reflective_injector.js:636:0
    _new@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31175:41 <- node_modules/@angular/core/src/di/reflective_injector.js:625:0
    getObjByKeyId@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:30827:54 <- node_modules/@angular/core/src/di/reflective_injector.js:277:0
    _getByKeyDefault@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31355:51 <- node_modules/@angular/core/src/di/reflective_injector.js:805:0
    _getByKey@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31327:41 <- node_modules/@angular/core/src/di/reflective_injector.js:777:0
    _getByReflectiveDependency@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31317:30 <- node_modules/@angular/core/src/di/reflective_injector.js:767:0
    _instantiate@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31216:62 <- node_modules/@angular/core/src/di/reflective_injector.js:666:0
    _instantiateProvider@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31186:37 <- node_modules/@angular/core/src/di/reflective_injector.js:636:0
    _new@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31175:41 <- node_modules/@angular/core/src/di/reflective_injector.js:625:0
    getObjByKeyId@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:30827:54 <- node_modules/@angular/core/src/di/reflective_injector.js:277:0
    _getByKeyDefault@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31355:51 <- node_modules/@angular/core/src/di/reflective_injector.js:805:0
    _getByKey@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31327:41 <- node_modules/@angular/core/src/di/reflective_injector.js:777:0
    _getByReflectiveDependency@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31317:30 <- node_modules/@angular/core/src/di/reflective_injector.js:767:0
    _instantiate@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31214:62 <- node_modules/@angular/core/src/di/reflective_injector.js:664:0
    _instantiateProvider@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31186:37 <- node_modules/@angular/core/src/di/reflective_injector.js:636:0
    _new@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31175:41 <- node_modules/@angular/core/src/di/reflective_injector.js:625:0
    getObjByKeyId@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:30827:54 <- node_modules/@angular/core/src/di/reflective_injector.js:277:0
    _getByKeyDefault@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31355:51 <- node_modules/@angular/core/src/di/reflective_injector.js:805:0
    _getByKey@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31327:41 <- node_modules/@angular/core/src/di/reflective_injector.js:777:0
    get@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31136:30 <- node_modules/@angular/core/src/di/reflective_injector.js:586:0
    /var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:39626:74 <- node_modules/@angular/core/testing/test_injector.js:55:0
    map@[native code]
    apply@[native code]
    call@[native code]
    call@[native code]
    map@/Users/tyrion/devel/saveup-front/node_modules/es6-shim/es6-shim.js:289:20
    execute@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:39626:32 <- node_modules/@angular/core/testing/test_injector.js:55:0
    /var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:39720:62 <- node_modules/@angular/core/testing/test_injector.js:149:0
    _instantiate@/var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:31312:97 <- node_modules/@angular/core/src/di/reflective_injector.js:762:0
    TypeError: undefined is not an object (evaluating 'authService.logout') in /var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify (line 891)
    /var/folders/zb/tpysrhsx7hbg1dnsn4gwtqq00000gn/T/0e62517ab3b76b1126894e51cc1d066a.browserify:891:20 <- app/shared/auth/auth-service/auth.service.spec.ts:110:20
PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 2 of 2 (1 FAILED) (0.187 secs / 0.026 secs)

karma.conf.js

// Karma configuration

module.exports = function (config) {
    config.set({

        // base path that will be used to resolve all patterns (eg. files, exclude)
        basePath: '',

        // frameworks to use
        // available frameworks: http://ift.tt/1ft83uu
        frameworks: ['jasmine', 'browserify'],

        // list of files / patterns to load in the browser
        files: [
            "node_modules/es6-shim/es6-shim.js",        // TypeError: undefined is not a constructor (evaluating "new exports.Map()")
            "node_modules/reflect-metadata/Reflect.js", // "Uncaught reflect-metadata shim is required when using class decorators"
            "node_modules/zone.js/dist/zone.js",        // Zone.js dependencies (Zone undefined)
            "node_modules/http://ift.tt/1KReLA0",
            "node_modules/http://ift.tt/2anIl3w",
            "node_modules/http://ift.tt/2b8mEkP",
            "vendors/lock-9.1.js",
            "app/**/*.spec.ts",
            {pattern: "node_modules/reflect-metadata/Reflect.js.map", included: false, served: true}, // 404 on the same
            {pattern: "www/build/**/*.html", served: true, included: true},
            {pattern: "app/**/*.html", served: true, included: true},
        ],


        // list of files to exclude
        exclude: [
            "node_modules/angular2/**/*_spec.js",
            "node_modules/ionic-angular/**/*spec*"
        ],


        // preprocess matching files before serving them to the browser
        // available preprocessors: http://ift.tt/1gyw6MG
        preprocessors: {
            '**/*.ts': ['browserify']
        },

        browserify: {
            debug: true,
            transform: [
                ['browserify-istanbul', {
                    instrumenter: require('isparta'),
                    ignore: ['**/*.spec.ts', '**/*.d.ts'],
                }]
            ],
            plugin: [
                ['tsify']
            ]
        },

        // test results reporter to use
        // possible values: 'dots', 'progress'
        // available reporters: http://ift.tt/1ft83KQ
        reporters: ['verbose', 'progress'],

        // web server port
        port: 9876,


        // enable / disable colors in the output (reporters and logs)
        colors: true,

        proxies: {
            '/build': '/base/www/build'
        },


        // level of logging
        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
        logLevel: config.LOG_ERROR,


        // enable / disable watching file and executing tests whenever any file changes
        autoWatch: true,

        // start these browsers
        // available browser launchers: http://ift.tt/1ft83KU
        browsers: ['PhantomJS2_custom'],

        // you can define custom flags
        customLaunchers: {
            'PhantomJS2_custom': {
                base: 'PhantomJS2',
                options: {
                    windowName: 'my-window',
                    settings: {
                        webSecurityEnabled: false
                    },
                },
                flags: ['--load-images=true'],
                debug: true
            }
        },

        phantomjsLauncher: {
            // Have phantomjs exit if a ResourceError is encountered (useful if karma exits without killing phantom)
            exitOnResourceError: true
        },

        // Continuous Integration mode
        // if true, Karma captures browsers, runs the tests and exits
        singleRun: true,

        // Concurrency level
        // how many browser should be started simultaneous
        concurrency: Infinity
    })
};

gulpfile.js

var gulp = require('gulp'),
    gulpWatch = require('gulp-watch'),
    del = require('del'),
    runSequence = require('run-sequence'),
    Server = require('karma').Server,
    argv = process.argv,
    jasmine = require('gulp-jasmine');

gulp.task('serve:before', ['watch']);
gulp.task('emulate:before', ['build']);
gulp.task('deploy:before', ['build']);
gulp.task('build:before', ['build']);

var shouldWatch = argv.indexOf('-l') > -1 || argv.indexOf('--livereload') > -1;
gulp.task('run:before', [shouldWatch ? 'watch' : 'build']);

var buildBrowserify = require('ionic-gulp-browserify-typescript');
var buildSass = require('ionic-gulp-sass-build');
var copyHTML = require('ionic-gulp-html-copy');
var copyFonts = require('ionic-gulp-fonts-copy');
var copyScripts = require('ionic-gulp-scripts-copy');
var isRelease = argv.indexOf('--release') > -1;

gulp.task('sass', buildSass);
gulp.task('html', copyHTML);
gulp.task('fonts', copyFonts);
gulp.task('scripts', copyScripts);
gulp.task('clean', function () {
    return del('www/build');
});

gulp.task('scripts', function () {
    return copyScripts({
        src: [
            'node_modules/es6-shim/es6-shim.min.js',
            'node_modules/es6-shim/es6-shim.map',
            'node_modules/zone.js/dist/zone.js',
            'node_modules/reflect-metadata/Reflect.js',
            'node_modules/reflect-metadata/Reflect.js.map',
            'vendors/*.js',
            'www/favicon.ico'
        ],
        dest: 'www/build/js'
    });
});

gulp.task('watch', ['clean'], function (done) {
    runSequence(
        ['sass', 'html', 'fonts', 'scripts'],
        function () {
            gulpWatch('app/**/*.scss', function () {
                gulp.start('sass');
            });
            gulpWatch('app/**/*.html', function () {
                gulp.start('html');
            });
            buildBrowserify({
                watch: true, browserifyOptions: {
                }
            }).on('end', done);
        }
    );
});

gulp.task('build', ['clean'], function (done) {
    runSequence(
        ['sass', 'html', 'fonts', 'scripts'],
        function () {
            buildBrowserify({
                minify: isRelease,
                browserifyOptions: {
                    debug: !isRelease
                },
                uglifyOptions: {
                    mangle: false
                }
            }).on('end', done);
        }
    );
});

gulp.task('test', ['clean'], function (done) {
    runSequence(
        ['sass', 'html', 'fonts', 'scripts'],
        function () {
            var karmaServer = new Server({
                configFile: __dirname + '/karma.conf.js',
                singleRun: true
            }, function (exitCode) {
                done();
                process.exit(exitCode);
            }).start();
        })
});

gulp.task('tdd', ['clean'], function (done) {
    runSequence(
        ['sass', 'html', 'fonts', 'scripts'],
        function () {
            var karmaServer = new Server({
                configFile: __dirname + '/karma.conf.js'
            }, function () {
                done();
            }).start();
        })
});

Aucun commentaire:

Enregistrer un commentaire