2016-02-15 18 views
9

Buduję aplikację internetową przy użyciu Angular 2, SystemJS i Karma do testów.Węzeł obciążenia modułu z SystemJS i Karma w Angular 2

Próbuję załadować moduł węzła ngrx/store w teście:

import { 
    it, describe, expect, beforeEach, inject 
} from 'angular2/testing'; 

import { Store } from '@ngrx/store'; 

describe('Graphs store',() => { 
    let graphs; 

    beforeEach(inject([Store], (store: Store<any>) => { 
    graphs = store.select('graphs'); 
    })); 

    it('works',() => { 
    // expect graphs to do something... 
    }); 
}); 

Jednak moje badania nie powiedzie się z następującym komunikatem:

404: /@ngrx/store 
Chrome 48.0.2564 (Mac OS X 10.11.3) ERROR 
    Error: XHR error (404 Not Found) loading http://localhost:9876/@ngrx/store 

I rzeczywiście miał ten sam problem w dev jak się okazało, SystemJS nie wiedział, gdzie znaleźć @ngrx/store. Aby rozwiązać ten problem, zrobiłem to:

System.config({ 
    packages: { 
    src: { 
     format: 'register', 
     defaultExtension: 'js' 
    } 
    }, 
    map: { '@ngrx/store' : 'node_modules/@ngrx/store/dist/store.js' } // <-- this 
}); 

Zmodyfikowałem plik Shim Karma, aby zrobić to samo. Po zakonczeniu testów po raz drugi, teraz uzyskać inny błąd:

404: /node_modules/@ngrx/store/dist/store.js 
Chrome 48.0.2564 (Mac OS X 10.11.3) ERROR 
    Error: XHR error (404 Not Found) loading http://localhost:9876/node_modules/@ngrx/store/dist/store.js 

Oznacza to, że musi być przy wyraźnej ścieżki dałem go pod uwagę, ale wciąż nie może znaleźć modułu. Jest to poprawna ścieżka do modułu i działa po załadowaniu do przeglądarki.

Jestem dość zagubiony, co robić dalej. Czy ktoś może wskazać mi właściwy kierunek?

kilka rzeczy do uwaga:

  • Dodanie modułu węzła do files tablicy Karma nie jest opcją, ponieważ jego zależności muszą zostać rozwiązane z SystemJS
  • Dzieje się tak tylko z modułów węzła, dla którego SystemJS potrzebuje niestandardowych instrukcji, gdzie się znajdują. Mogę załadować inne moduły dobrze w moich testów bez podania konkretnej lokalizacji, jak długie SystemJS jest w stanie go znaleźć

Oto moja konfiguracja Karma:

// Set up with the help of 
// http://twofuckingdevelopers.com/2016/01/testing-angular-2-with-karma-and-jasmine/ 

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

    basePath: '.', 

    frameworks: ['jasmine'], 

    files: [ 
     // paths loaded by Karma 
     {pattern: 'node_modules/angular2/bundles/angular2-polyfills.js', included: true, watched: true}, 
     {pattern: 'node_modules/systemjs/dist/system.src.js', included: true, watched: true}, 
     {pattern: 'node_modules/rxjs/bundles/Rx.js', included: true, watched: true}, 
     {pattern: 'node_modules/angular2/bundles/angular2.dev.js', included: true, watched: true}, 
     {pattern: 'node_modules/angular2/bundles/testing.dev.js', included: true, watched: true}, 
     {pattern: 'karma-test-shim.js', included: true, watched: true}, 

     // paths loaded via module imports 
     {pattern: 'src/**/*.js', included: false, watched: true}, 

     // paths to support debugging with source maps in dev tools 
     {pattern: 'src/**/*.ts', included: false, watched: false}, 
     {pattern: 'src/**/*.js.map', included: false, watched: false} 
    ], 

    // proxied base paths 
    proxies: { 
     // required for component assets fetched by Angular's compiler 
     '/src/': '/base/src/' 
    }, 

    port: 9876, 

    logLevel: config.LOG_INFO, 

    colors: true, 

    autoWatch: true, 

    browsers: ['Chrome'], 

    // Karma plugins loaded 
    plugins: [ 
     'karma-jasmine', 
     'karma-coverage', 
     'karma-chrome-launcher' 
    ], 

    // // Coverage reporter generates the coverage 
    // reporters: ['progress', 'dots', 'coverage'], 
    // 
    // // Source files that you wanna generate coverage for. 
    // // Do not include tests or libraries (these files will be instrumented by Istanbul) 
    // preprocessors: { 
    // 'src/**/!(*spec).js': ['coverage'] 
    // }, 

    // coverageReporter: { 
    // reporters:[ 
    //  {type: 'json', subdir: '.', file: 'coverage-final.json'} 
    // ] 
    // }, 

    singleRun: true 
    }) 
}; 

I tu jest moje Karma podkładka:

// Tun on full stack traces in errors to help debugging 
Error.stackTraceLimit = Infinity; 

jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000; 

// // Cancel Karma's synchronous start, 
// // we will call `__karma__.start()` later, once all the specs are loaded. 
__karma__.loaded = function() {}; 

System.config({ 
    packages: { 
    'base/src': { 
     defaultExtension: 'js', 
     format: 'register', 
     map: Object.keys(window.__karma__.files).filter(onlyAppFiles).reduce(createPathRecords, {}) 
    } 
    }, 
    // This makes it work in the browser, but not in my tests! 
    paths: { '@ngrx/store' : 'node_modules/@ngrx/store/dist/store.js' } 
}); 

System.import('angular2/src/platform/browser/browser_adapter') 
    .then(function(browser_adapter) { browser_adapter.BrowserDomAdapter.makeCurrent(); }) 
    .then(function() { return Promise.all(resolveTestFiles()); }) 
    .then(function() { __karma__.start(); }, function(error) { __karma__.error(error.stack || error); }); 

function createPathRecords(pathsMapping, appPath) { 
    // creates local module name mapping to global path with karma's fingerprint in path, e.g.: 
    // './vg-player/vg-player': 
    // '/base/src/vg-player/vg-player.js?f4523daf879cfb7310ef6242682ccf10b2041b3e' 
    var pathParts = appPath.split('/'); 
    var moduleName = './' + pathParts.slice(Math.max(pathParts.length - 2, 1)).join('/'); 
    moduleName = moduleName.replace(/\.js$/, ''); 
    pathsMapping[moduleName] = appPath + '?' + window.__karma__.files[appPath]; 
    return pathsMapping; 
} 

function onlyAppFiles(filePath) { 
    return /\/base\/src\/(?!.*\.spec\.js$).*\.js$/.test(filePath); 
} 

function onlySpecFiles(path) { 
    return /\.spec\.js$/.test(path); 
} 

function resolveTestFiles() { 
    return Object.keys(window.__karma__.files) // All files served by Karma. 
    .filter(onlySpecFiles) 
    .map(function(moduleName) { 
     // loads all spec files via their global module names (e.g. 
     // 'base/src/vg-player/vg-player.spec') 
     return System.import(moduleName); 
    }); 
} 

Aktualizacja

jest przykładem repozytorium z błędem here. Możesz zobaczyć konkretne zmiany, które powodują błąd here. Uruchom $ npm install i $ npm test, aby uzyskać błąd.

+0

jestem obliczu podobnych problemów podczas testowania od przeglądarka. Ścieżki wydają się tu być problemem. Jakieś aktualizacje na ten temat lub czy problem został rozwiązany? – Gary

+0

Nie rozwiązano jeszcze. Myśląc o otwarciu nagrody. Muszę to naprawić. – weltschmerz

+0

Czy możesz przesłać [mcve] (http://stackoverflow.com/help/mcve) jako repozytorium git? –

Odpowiedz

7

W tym @ngrx/store wraz z pozostałymi pakietami zostanie rozwiązany błąd 404:

// for testing in karma.conf.js 
    files: [ 
     // paths loaded by Karma 
     {pattern: 'node_modules/@ngrx/store/dist/store.js', included: true, watched: true}, 
    ], 

Ale w przeciwieństwie do pozostałych wiązek, które są skompilowane jako moduły systemowe, @ngrx/store jest kompilowany jako commonjs modułu

// 'node_modules/angular2/bundles/angular2.dev.js' 
"format register"; 
System.register("angular2/src/facade/lang", [], true, function(require, exports, module) { 
.... 

// 'node_modules/rxjs/bundles/Rx.js' 
"format register"; 
System.register("rxjs/util/root", [], true, function(require, exports, module) { 
.... 

// 'node_modules/@ngrx/store/dist/store.js' 
.... 
var Observable_1 = require('rxjs/Observable'); 
.... 

który powoduje błąd:

Uncaught ReferenceError: require is not defined

// with {pattern: '~/store.js', indluded: true} 
// context.html includes 
<script type="text/javascript" src="/base/node_modules/@ngrx/store/dist/store.js?fb5e807149603c3c2f998c98faf6826c7e301d71"></script> 

Dlatego nie powinien go obejmować:

{pattern: 'node_modules/@ngrx/store/dist/store.js', included: false, watched: true} 

Zasadniczo będzie to lista w obiekcie window.__karma__.files, ale nie zostanie dodany jako skrypt w kodzie karmy: context.html - przeglądarka nie załaduje się i nie uruchomi kodu powodującego błąd. Ładowanie powinno być obsługiwane przez SystemJS ...

Jeśli przeprowadzasz testy karmy za pomocą singleRun: false, możesz sprawdzić pliki w Chrome Devtools> Sieć. Zobaczysz tam listę plików załadowanych i tam ostatni element układanki jest:

W swojej karma-test-shim.js zmiany System.config.map do:

map: { '@ngrx/store' : '/base/node_modules/@ngrx/store/dist/store.js' } 

Executed 4 of 4 SUCCESS (0.037 secs/0.008 secs)

+0

Nice. Dziękuję Ci. – weltschmerz

+0

Musiałeś więc usunąć wzorzec z 'files' i dodać' map' do System.config? –

+0

@mithun_daa Musisz zachować wzór w 'files []', lub plik nie zostanie wyświetlony, gdy SystemJS spróbuje go wczytać. Musisz tylko ustawić 'include: false', aby nie był załadowany i wykonany przez przeglądarkę, i pozostaw ładowanie do SystemJS. – Sasxa

0

Wysłano wiadomość z poprawką.Nie może być lepszy sposób to zrobić, ale to działa:

skopiować plik store.js do folderu dist aktualizując package.json „s build skrypt

... && cp node_modules/@ngrx/store/dist/store.js dist/store.js 

zaktualizować ścieżka w karma-test.shim.js

paths: { '@ngrx/store' : '/base/dist/store.js' } 
+2

Dzięki za PR, ale to nie zadziała. Zasadniczo to samo, co po prostu przesuwanie paczki. Nie skaluje się również, jeśli ma to miejsce w przypadku większej liczby pakietów. Chciałbym zrozumieć, dlaczego SystemJS nie może załadować modułu i znaleźć dla niego poprawki. – weltschmerz

+0

Mam również problemy z pathing, Karma i SystemJS. Czy było jakieś rozwiązanie? –

Powiązane problemy