【问题标题】:How do I test angular2 services that use moment?如何测试使用矩的 angular2 服务?
【发布时间】:2017-10-30 16:05:31
【问题描述】:

我正在尝试测试我编写的使用 momentJS 的 Angular (angular2) 服务,但由于 moment 存在于浏览器中,因此我不断收到引用错误。无论如何告诉业力/茉莉花如何在单元测试中使用时刻?这是我得到的错误:

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);
};

【问题讨论】:

    标签: angular momentjs


    【解决方案1】:

    我最终做了一些非常老套的事情。我使用 require 从我的 node_modules 导入矩库并将其附加到每个使用矩的测试类的 beforeEach 中的窗口对象。如果有人有更好,更少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
    
    });
    

    【讨论】:

      【解决方案2】:

      我最近遇到了这个问题,并通过在测试框架中包含 moment 来解决。在我们的例子中,moment 附加到窗口,所以最终在我们的测试配置中这样做:

      window.moment = require('moment-recur');
      

      您可能需要做一些类似的事情来适应您的情况。

      【讨论】:

        【解决方案3】:

        对我来说,解决方案是在我的 TestBed 中导入 MomentModule

        import { MomentModule } from 'angular2-moment';
            ...
            beforeEach(async(() => {
            TestBed.configureTestingModule({
            declarations: [MyComponent],
            imports: [MomentModule],
            ...
        

        取自https://github.com/urish/ngx-moment/issues/165

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-03-14
          • 1970-01-01
          • 2015-12-26
          • 1970-01-01
          • 2018-12-23
          • 1970-01-01
          • 2016-10-31
          相关资源
          最近更新 更多