25

我一直无法让我的测试 jasmine 测试套件与 webpack 4 一起运行。升级 webpack 后,几乎每个测试都会出现以下错误:

Error: <spyOn> : getField is not declared writable or has no setter 

这是由于我们用来为简单函数创建间谍的常见模式是:

import * as mod from 'my/module';
//...
const funcSpy = spyOn(mod, 'myFunc');

我玩过,module.rules[].type但似乎没有一个选项可以解决问题。

这个 webpack GH 问题表明 ECMA 模块是不可写的,这对 web 是有意义的,但是真的没有测试的解决方法吗?

相关软件包版本:

"jasmine-core": "2.6.4",
"typescript": "2.5.3",
"webpack": "4.1.1",
"webpack-cli": "^2.0.12",
"karma": "^0.13.22",
"karma-jasmine": "^1.1.0",
"karma-webpack": "^2.0.13",
4

4 回答 4

23

通过将参数设置为 ,可以spyOnProperty将属性视为只读。accessType'get'

然后你的设置看起来像

import * as mod from 'my/module';
//...
const funcSpy = jasmine.createSpy('myFunc').and.returnValue('myMockReturnValue');
spyOnProperty(mod, 'myFunc', 'get').and.returnValue(funcSpy);
于 2019-02-19T00:29:26.407 回答
3

这个 GitHub 问题上,他们得出了相同的结论;不可变的出口是有意的。但是用户lavelle有一个解决方法(在此评论中),他们为测试和生产代码创建了不同的 webpack 配置。测试配置使用"commonjs"模块,这似乎通过不创建 getter 来为他们工作。

于 2018-09-06T21:27:34.110 回答
3

添加到@Anton Poznyakovskiy 的答案:

为了方便起见,我已将此 TypeScript 函数添加到我的共享测试模块中:

export const spyOnFunction = <T>(obj: T, func: keyof T) => {
  const spy = jasmine.createSpy(func as string);
  spyOnProperty(obj, func, 'get').and.returnValue(spy);

  return spy;
};

示例用法:

import * as mod from 'my/module';
//...
spyOnFunction(mod, 'myFunc').and.returnValue('myMockReturnValue');
于 2019-03-05T17:56:29.553 回答
0

为了解决这个问题,可以将方法包装在自定义类中,然后模拟它。

下面的例子:

//Common Utility

import * as library from './myLibrary'

export class CustomWrapper{
    static _func = library.func;
}

//Code File
import { CustomWrapper } from './util/moduleWrapper';

const output = CustomWrapper._func(arg1, arg2);

//Test File 

import { CustomWrapper } from './util/moduleWrapper';

spyOn(CustomWrapper, '_func').and.returnValue('mockedResult');
于 2021-01-16T11:04:51.317 回答