2017-01-26 2 views
0

Я пытаюсь ознакомиться с модульным тестированием в приложении Angular2 и выполнял документацию по угловому алгоритму, но столкнулся с ошибкой, которую я не смог выполнить выяснить.Ошибка при попытке протестировать компонент Angular2 с внешним шаблоном

У меня есть простое демонстрационное приложение, которое я собрал для игры с тестированием. У меня есть настройка и настройка в точности как мой полный проект. Это приложение Angular2, построенное поверх ASP.NET Core MVC, с использованием шаблонов и настроек, представленных здесь (https://marketplace.visualstudio.com/items?itemName=MadsKristensen.ASPNETCoreTemplatePack). Я использую Webpack и Typcript с кармой и жасмином для модульного тестирования.

Проблема, с которой я столкнулся, заключается в том, что когда я пытаюсь реализовать тесты для компонента с внешним шаблоном (https://angular.io/docs/ts/latest/guide/testing.html#!#async-in-before-each), я получаю сообщение об ошибке в async beforeEach. Хотя все мои тесты проходят успешно, я получаю сообщение об ошибке в своем редакторе и при запуске полного приложения. Ошибка, которую я получаю: error TS2345: Argument of type '(done: any) => any' is not assignable to parameter of type '() => void'.

Хотя моим предпочтительным решением было бы исправить ошибку, поскольку мои тесты проходят, я бы согласился на то, чтобы настроить все, чтобы мои файлы .spec.ts не были включены в пучки Webpack создает для сайта прода (обратите внимание на мой spec.ts файлы живут бок о боке с .ts файлами, которые реализуют компоненты)

banner.component.spec.ts

import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 
import { By } from '@angular/platform-browser'; 
import { DebugElement } from '@angular/core'; 

import { BannerComponent } from '../banner.component'; 

describe('BannerComponent (templateUrl)',() => { 

    let comp: BannerComponent; 
    let fixture: ComponentFixture<BannerComponent>; 
    let de: DebugElement; 
    let el: HTMLElement; 

    // async beforeEach 
    //This is the function that is producing the error 
    beforeEach(async(() => { 
     TestBed.configureTestingModule({ 
      declarations: [BannerComponent], // declare the test component 
     }) 
     .compileComponents(); // compile template and css 
    })); 

    // synchronous beforeEach 
    beforeEach(() => { 
     fixture = TestBed.createComponent(BannerComponent); 

     comp = fixture.componentInstance; // BannerComponent test instance 

     // query for the title <h1> by CSS element selector 
     de = fixture.debugElement.query(By.css('h1')); 
     el = de.nativeElement; 
    }); 

    it('no title in the DOM until manually call `detectChanges`',() => { 
     expect(el.textContent).toEqual(''); 
    }); 

    it('should display original title',() => { 
     fixture.detectChanges(); 
     expect(el.textContent).toContain(comp.title); 
    }); 

    it('should display a different test title',() => { 
     comp.title = 'Test Title'; 
     fixture.detectChanges(); 
     expect(el.textContent).toContain('Test Title'); 
    }); 

}); 

карма .conf.js:

'use strict'; 

module.exports = (config) => { 
    config.set({ 
     autoWatch: true, 
     browsers: ['Chrome', 'PhantomJS'], 
     files: [ 
      './node_modules/es6-shim/es6-shim.min.js', 
      './karma.entry.js' 
     ], 
     frameworks: ['jasmine'], 
     logLevel: config.LOG_INFO, 
     phantomJsLauncher: { 
      exitOnResourceError: true 
     }, 
     preprocessors: { 
      'karma.entry.js': ['webpack', 'sourcemap'] 
     }, 
     reporters: ['progress', 'growl'], 
     singleRun: false, 
     webpack: require('./webpack.config.test'), 
     webpackMiddleware: { 
      noInfo: true 
     } 
    }); 
}; 

karma.entry.js

require('es6-shim'); 
require('reflect-metadata'); 
require('zone.js/dist/zone'); 
require('zone.js/dist/long-stack-trace-zone'); 
require('zone.js/dist/async-test'); 
require('zone.js/dist/fake-async-test'); 
require('zone.js/dist/sync-test'); 
require('zone.js/dist/proxy'); // since zone.js 0.6.14 
require('zone.js/dist/jasmine-patch'); 

const browserTesting = require('@angular/platform-browser-dynamic/testing'); 
const coreTesting = require('@angular/core/testing'); 

coreTesting.TestBed.resetTestEnvironment(); 
coreTesting.TestBed.initTestEnvironment(
    browserTesting.BrowserDynamicTestingModule, 
    browserTesting.platformBrowserDynamicTesting() 
); 

const context = require.context('./ClientApp/app/', true, /\.spec\.ts$/); 

context.keys().forEach(context); 

Error.stackTraceLimit = Infinity; 
jasmine.DEFAULT_TIMEOUT_INTERVAL = 2000; 

webpack.config.test.js

'use strict'; 

const path = require('path'); 
const webpack = require('webpack'); 

module.exports = { 
    devtool: 'inline-source-map', 
    module: { 
     loaders: [ 
      { loader: 'raw', test: /\.(css|html)$/ }, 
      { test: /\.ts$/, exclude: /node_modules/, include: /ClientApp/, loader: 'ts', query: { silent: true } }, 
      { test: /\.(png|jpg|jpeg|gif|woff|woff2|eot|ttf|svg)(\?|$)/, loader: 'url-loader?limit=100000' }, 
     ] 
    }, 
    resolve: { 
     extensions: ['', '.js', '.ts'], 
     modulesDirectories: ['node_modules'], 
     root: path.resolve('.', 'ClientApp/app') 
    } 
}; 

webpack.config.js

/// <binding ProjectOpened='Watch - Development' /> 
var isDevBuild = process.argv.indexOf('--env.prod') < 0; 
var path = require('path'); 
var webpack = require('webpack'); 
var nodeExternals = require('webpack-node-externals'); 
var merge = require('webpack-merge'); 
var allFilenamesExceptJavaScript = /\.(?!js(\?|$))([^.]+(\?|$))/; 

// Configuration in common to both client-side and server-side bundles 
var sharedConfig = { 
    resolve: { extensions: [ '', '.js', '.ts' ] }, 
    output: { 
     filename: '[name].js', 
     publicPath: '/dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix 
    }, 
    module: { 
     loaders: [ 
      { test: /\.ts$/, include: /ClientApp/, loader: 'ts', query: { silent: true } }, 
      { test: /\.html$/, loader: 'raw' }, 
      { test: /\.css$/, loader: 'to-string!css' }, 
      { test: /\.(png|jpg|jpeg|gif|svg)$/, loader: 'url', query: { limit: 25000 } } 
     ] 
    } 
}; 

// Configuration for client-side bundle suitable for running in browsers 
var clientBundleConfig = merge(sharedConfig, { 
    entry: { 'main-client': './ClientApp/boot-client.ts' }, 
    output: { path: path.join(__dirname, './wwwroot/dist') }, 
    devtool: isDevBuild ? 'inline-source-map' : null, 
    plugins: [ 
     new webpack.DllReferencePlugin({ 
      context: __dirname, 
      manifest: require('./wwwroot/dist/vendor-manifest.json') 
     }) 
    ].concat(isDevBuild ? [] : [ 
     // Plugins that apply in production builds only 
     new webpack.optimize.OccurenceOrderPlugin(), 
     new webpack.optimize.UglifyJsPlugin() 
    ]) 
}); 

// Configuration for server-side (prerendering) bundle suitable for running in Node 
var serverBundleConfig = merge(sharedConfig, { 
    entry: { 'main-server': './ClientApp/boot-server.ts' }, 
    output: { 
     libraryTarget: 'commonjs', 
     path: path.join(__dirname, './ClientApp/dist') 
    }, 
    target: 'node', 
    devtool: 'inline-source-map', 
    externals: [nodeExternals({ whitelist: [allFilenamesExceptJavaScript] })] // Don't bundle .js files from node_modules 
}); 

module.exports = [clientBundleConfig, serverBundleConfig]; 
+0

Вы не выполняете асинхронную работу в обратном вызове, поэтому зачем использовать async (...)? –

+0

@AluanHaddad Это async, потому что тестируемый компонент имеет внешний шаблон. Поскольку чтение этого файла необходимо для создания компонента, и это операция asnyc, тестовая установка должна быть асинхронной, чтобы внешний файл шаблона был прочитан, прежде чем он попытается создать экземпляр компонента. Вы можете узнать больше об этом в документации по угловому запросу на странице https://angular.io/docs/ts/latest/guide/testing.html#!#component-with-external-template – Hamman359

ответ

0

Похоже, я понял, что я вопрос. При настройке проекта я, по-видимому, установил старую версию '@types/jasmine', которая, по-видимому, имеет другую сигнатуру метода для beforeEach(), которая не могла принять сделанное: любое возвращаемое функцией async(). Я обновил файл '@types/jasmine' до последней версии, поддерживающей эту версию beforeEach(), все мои ошибки ушли.

Смежные вопросы