【问题标题】:Getting tz is not a function error when testing a method in Angular 2 service that uses moment-timezone在使用时刻时区的 Angular 2 服务中测试方法时,获取 tz 不是函数错误
【发布时间】:2025-12-11 11:55:01
【问题描述】:

在测试使用moment.tz(time) 功能的方法时,我收到__WEBPACK_IMPORTED_MODULE_2_moment__.tz is not a function。 当我只测试一个使用moment.js 的虚拟函数时,一切都很好。

我检查了 karma 和 webpack 配置,但他们没有在任何地方提到时刻。根据我的推理,如果在 webpack 和 karma 配置中没有明确提及 moment 可以在这样的单元测试中工作,那么 moment-timezone 也应该如此。

这里是服务的单元测试文件:

//note.service.spec.ts
import {TestBed, inject} from '@angular/core/testing';
import {BrowserDynamicTestingModule, platformBrowserDynamicTesting} from "@angular/platform-browser-dynamic/testing";
import {NoteService} from './note.service';

import * as moment from 'moment'; //xavtodo: maybe not needed

describe('NoteService', () => {
  let service: NoteService;

  beforeEach(() => {
    TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting())
        .configureTestingModule({
          providers: [NoteService]
        });
  });

  afterEach(() => {
    TestBed.resetTestEnvironment();
  });

  beforeEach(inject([NoteService], (s: NoteService) => {
    service = s;
  }));

  it('should be created', inject([NoteService], (service: NoteService) => {
    expect(service).toBeTruthy();
  }));

  it('DUMMY WITH MOMENTJS', inject([NoteService], (service: NoteService) => { //so this one is working with moment.js
      expect(service.dummy()).toBeTruthy();
  }));

  it('DUMMY WITH MOMENT-TIMEZONE', inject([NoteService], (service: NoteService) => { //this one isn't with moment timezone
    expect(service.dummytz()).toBeTruthy();
  }));

});

我正在测试 note.service.ts 中的 dummydummytz 函数以隔离错误:

dummy(): Moment{
  return moment();
}

dummytz(): Moment{
  return moment.tz('Europe/London');
}

显然,tz() 函数似乎没有在时刻定义,webpack 在单元测试中没有选择时刻时区,但它在应用程序中选择它没问题。

这是webpack.unit.test.js 配置文件:

const webpack = require('webpack');
const helpers = require('./helpers');
const commonConfig = require('./webpack.common.js');
const ExtractTextPlugin = require('extract-text-webpack-plugin');

console.log('///////////////////////////UNIT TEST');

module.exports = {
    devtool: 'inline-source-map',

    node: {
        fs: 'empty'
    },

    resolve: {
        extensions: ['.ts', '.js']
    },

    module: commonConfig.module,

    plugins: [
        new webpack.ContextReplacementPlugin(
            // The (\\|\/) piece accounts for path separators in *nix and Windows
            /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
            helpers.root('./src'), // location of your src
            {} // a map of your routes
        ),

        new ExtractTextPlugin({ filename: 'main.css', disable: false, allChunks: true})
    ]
}

【问题讨论】:

  • 您是在将时刻时区导入您的服务还是在您使用它的任何地方
  • 不必。只需将其添加到 package.json ,当我使用 moment.tz() 时,webpack 会处理它。

标签: angular unit-testing webpack momentjs karma-runner


【解决方案1】:

您如何以及在哪里导入时刻?看来你不见了

var moment = require('moment-timezone');

更多详情are here如何使用moment().tz

【讨论】:

  • 我将这一行 require('moment-timezone'); 放在了 note.service.spec.ts 的顶部,测试变成了绿色。但是,每次我测试使用时区功能的组件或服务方法时,我都必须在规范文件中删除 require('moment-timezone');。有没有更好的办法?我不必要求生产代码工作的时刻时区,那么为什么需要单元测试呢?
  • 我建议创建一个 spec-helper.js 来满足时刻时区的要求,然后您可以让所有测试都需要该文件,或者将该文件包含在您的 karma.options.js files: [] 数组中
  • 好的,会的。感谢@olore 的帮助
最近更新 更多