Как я могу издеваться над импортом модуля ES6 с помощью Jest?



Я начинаю думать, что это невозможно, но я все равно хочу спросить.



Я хочу проверить, что один из моих модулей ES6 вызывает другой модуль ES6 определенным образом. С Жасмин это очень легко --



приложение код:



// myModule.js
import dependency from './dependency';

export default (x) => {
dependency.doSomething(x * 2);
}


и тестовый код:



//myModule-test.js
import myModule from '../myModule';
import dependency from '../dependency';

describe('myModule', () => {
it('calls the dependency with double the input', () => {
spyOn(dependency, 'doSomething');

myModule(2);

expect(dependency.doSomething).toHaveBeenCalledWith(4);
});
});


что такое эквивалент с шуткой? Я чувствую, что это такая простая вещь, чтобы хотеть сделать, но я рвал свои волосы, пытаясь понять это.



в ближе всего я пришел, заменив importС requires, и перемещение их внутри тестов / функций. Ни то, ни другое я не хочу делать.



// myModule.js
export default (x) => {
const dependency = require('./dependency'); // yuck
dependency.doSomething(x * 2);
}

//myModule-test.js
describe('myModule', () => {
it('calls the dependency with double the input', () => {
jest.mock('../dependency');

myModule(2);

const dependency = require('../dependency'); // also yuck
expect(dependency.doSomething).toBeCalledWith(4);
});
});


для бонусных очков, я хотел бы, чтобы все это работало, когда функция внутри dependency.js экспорт по умолчанию. Однако я знаю, что шпионаж за экспортом по умолчанию не работает в Jasmine (или, по крайней мере, я никогда не мог заставить его работать), поэтому я не надеюсь, что это возможно в шутку.

593   4  

4 ответов:

Я был в состоянии решить эту проблему с помощью взлома с участием import *. Он даже работает как для именованных, так и для экспорта по умолчанию!

для именованного экспорта:

// dependency.js
export const doSomething = (y) => console.log(y)

// myModule.js
import { doSomething } from './dependency';

export default (x) => {
  doSomething(x * 2);
}

// myModule-test.js
import myModule from '../myModule';
import * as dependency from '../dependency';

describe('myModule', () => {
  it('calls the dependency with double the input', () => {
    dependency.doSomething = jest.fn(); // Mutate the named export

    myModule(2);

    expect(dependency.doSomething).toBeCalledWith(4);
  });
});

или для экспорта по умолчанию:

// dependency.js
export default (y) => console.log(y)

// myModule.js
import dependency from './dependency'; // Note lack of curlies

export default (x) => {
  dependency(x * 2);
}

// myModule-test.js
import myModule from '../myModule';
import * as dependency from '../dependency';

describe('myModule', () => {
  it('calls the dependency with double the input', () => {
    dependency.default = jest.fn(); // Mutate the default export

    myModule(2);

    expect(dependency.default).toBeCalledWith(4); // Assert against the default
  });
});

как Михай Дамиан совершенно справедливо указал ниже, это мутация объекта модуля dependency, и поэтому он будет "протекать" через другие тесты. Поэтому, если вы используете этот подход, вы должны сохранить исходное значение, а затем снова установить его после каждого теста. Делать это легко, с шуткой, используйте spyOn() вместо jest.fn() потому что он поддерживает легко восстанавливать свое первоначальное значение, поэтому избегая ранее упомянутой "утечки".

вы должны издеваться над модулем и установить шпиона самостоятельно:

import myModule from '../myModule';
import dependency from '../dependency';
jest.mock('../dependency', () => ({
  doSomething: jest.fn()
}))

describe('myModule', () => {
  it('calls the dependency with double the input', () => {
    myModule(2);
    expect(dependency.doSomething).toBeCalledWith(4);
  });
});

добавление дополнительных ответов Андреаса. У меня была такая же проблема с кодом ES6, но я не хотел мутировать импорт. Это выглядело хаки. Так что я сделал это

import myModule from '../myModule';
import dependency from '../dependency';
jest.mock('../dependency');

describe('myModule', () => {
  it('calls the dependency with double the input', () => {
    myModule(2);
  });
});

и добавлена зависимость.js in"__глумится __" папка параллельно зависимости.js. Это сработало для меня. Кроме того, это дало мне возможность вернуть подходящие данные из макетной реализации. Убедитесь, что вы даете правильный путь к модулю, который вы хотите издеваться.

чтобы издеваться над экспортом модуля зависимостей ES6 по умолчанию с помощью jest:

import myModule from '../myModule';
import dependency from '../dependency';

jest.mock('../dependency');

// If necessary, you can place a mock implementation like this:
dependency.mockImplementation(() => 42);

describe('myModule', () => {
  it('calls the dependency once with double the input', () => {
    myModule(2);

    expect(dependency).toHaveBeenCalledTimes(1);
    expect(dependency).toHaveBeenCalledWith(4);
  });
});

другие варианты не работали для моего случая.

Comments

    Ничего не найдено.