Можно ли настроить модули webpack 4 так, чтобы Жасмин могла шпионить за их участниками?

Мне не удалось запустить тестовый пакет 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, но ни один из вариантов, похоже, не помогает.

Этот ошибка GH указывает на то, что модули ECMA не доступны для записи, что имеет смысл для Интернета. но действительно ли нет обходного пути для тестирования?

Соответствующие версии пакетов:

"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",

person Ryan    schedule 21.03.2018    source источник


Ответы (4)


Есть spyOnProperty, который позволяет рассматривать свойство как доступное только для чтения, присваивая аргументу accessType значение 'get'.

Тогда ваша установка будет выглядеть так

import * as mod from 'my/module';
//...
const funcSpy = jasmine.createSpy('myFunc').and.returnValue('myMockReturnValue');
spyOnProperty(mod, 'myFunc', 'get').and.returnValue(funcSpy);
person Anton Poznyakovskiy    schedule 19.02.2019
comment
Странно, но это не работает для меня. Это завершается со следующей ошибкой: ===Ошибка: ‹spyOnProperty›: myFunc не объявлен настраиваемым===. Вот как я объявил свою функцию: export var myFunc = function(){...}; - person Amer Mograbi; 14.02.2020
comment
См. функцию fixedSpyOn здесь github.com/jasmine/jasmine/issues/1414#issuecomment-457878397 - person Richard Collette; 23.03.2020

Добавление к ответу @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');
person Tom Faltesek    schedule 05.03.2019

Есть эта проблема GitHub, где они приходят к одному и тому же выводу; что неизменный экспорт предназначен. Но у пользователя lavelle есть обходной путь (в этом комментарии), где они создали разные конфигурации веб-пакетов для тестового и производственного кода. В тестовой конфигурации используются модули "commonjs", которые, похоже, сработали для них, не создавая геттеры.

person Cem Schemel    schedule 06.09.2018

Чтобы решить эту проблему, можно обернуть методы в пользовательский класс, а затем смоделировать его.

Пример ниже:

//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');
person Tushar Agey    schedule 16.01.2021