我正在尝试测试我编写的使用momentJS的Angular(angular2)服务,但是由于时刻存在于浏览器中,我不断收到引用错误。无论如何告诉karma / jasmine如何在单元测试中使用时刻?这是我得到的错误:
ReferenceError: Can't find variable: moment in karma-test-shim.js (line 33814)
以下是我的测试:
describe('isDateBeforeToday', () => {
it('should return true if date is before today', () => {
let past = new Date(2016, 1, 1);
expect(UnitService.isDateBeforeToday(past)).toEqual(true);
past = new Date();
past.setDate(past.getDate() - 1);
past.setHours(23);
expect(UnitService.isDateBeforeToday(past)).toEqual(true);
});
it('should return false if date is today', () => {
let today = new Date();
expect(UnitService.isDateBeforeToday(today)).toEqual(false);
});
it('should return false if date is in future', () => {
let future = new Date();
future.setDate(future.getDate() + 1);
expect(UnitService.isDateBeforeToday(future)).toEqual(false);
});
});
以下是我试图测试的功能:
static isDateBeforeToday(date: Date) {
let momentDate = moment(date);
let now = moment();
return (momentDate.diff(now, 'days') < 0);
}
karma-test-shim.js(基于角度示例):
Error.stackTraceLimit = Infinity;
require('core-js/es6');
require('core-js/es7/reflect');
require('zone.js/dist/zone');
require('zone.js/dist/long-stack-trace-zone');
require('zone.js/dist/proxy');
require('zone.js/dist/sync-test');
require('zone.js/dist/jasmine-patch');
require('zone.js/dist/async-test');
require('zone.js/dist/fake-async-test');
require('moment');
var appContext = require.context('../__tests__', true, /\.spec\.ts/);
appContext.keys().forEach(appContext);
var testing = require('@angular/core/testing');
var browser = require('@angular/platform-browser-dynamic/testing');
testing.TestBed.initTestEnvironment(browser.BrowserDynamicTestingModule, browser.platformBrowserDynamicTesting());
karma.conf.js:
var webpackConfig = require('./webpack.test');
module.exports = function (config) {
var _config = {
basePath: '',
browserNoActivityTimeout: 20000, // had to increase this for component unit tests to work
frameworks: ['jasmine'],
files: [
{pattern: './karma-test-shim.js', watched: false}
],
preprocessors: {
'./karma-test-shim.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only'
},
webpackServer: {
noInfo: true
},
reporters: ['progress','kjhtml'], //leave coverage reporter in for now, even though coverage not working
coverageReporter: {
type: 'html',
dir: '../coverage/'
},
browsers: ['phantomJS_without_security'],
customLaunchers: {
chrome_without_security: {
base: 'Chrome',
flags: ['--disable-web-security']
},
phantomJS_without_security: {
base:'PhantomJS',
options: {
windowName: 'Portal-tests',
settings: {
webSecurityEnabled: false
}
}
}
},
phantomjsLauncher: {
// Have phantomjs exit if a ResourceError is encountered (useful if karma exits without killing phantom)
exitOnResourceError: true
},
client: {
captureConsole: true
},
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: false,
singleRun: true
};
config.set(_config);
};
答案 0 :(得分:2)
我最后做了一些非常黑客的事情。我使用require从我的node_modules导入moment库,并将它附加到每个使用片刻的测试类的beforeEach中的window对象。如果有人有更好的,更少的hacky,请回复。
import { UnitService } from '../../src/app/services/unit.service';
let moment = require('moment');
describe('UnitService', () => {
beforeEach(() => {
(<any>window).moment = moment;
});
// Tests that use a function that uses moment go here
});
答案 1 :(得分:0)
对我来说,解决方法是将MomentModule导入我的TestBed中
import { MomentModule } from 'angular2-moment';
...
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MyComponent],
imports: [MomentModule],
...