2016-09-28 3 views
16

У меня есть следующий модуль Я пытаюсь проверить в Jest:Как издеваются импортируемого имени функции в Jest, когда модуль unmocked

// myModule.js 

export function otherFn() { 
    console.log('do something'); 
} 

export function testFn() { 
    otherFn(); 

    // do other things 
} 

Как было показано выше, она экспортирует некоторые названные функции и, что важно testFn использует otherFn ,

В Шутках, когда я пишу мое модульное тестирование для testFn, я хочу, чтобы дразнить функцию otherFn, потому что я не хочу ошибок в otherFn, чтобы повлиять на мое модульное тестирование для testFn. Моя проблема заключается в том, что я не уверен, что лучший способ сделать это:

// myModule.test.js 
jest.unmock('myModule'); 

import { testFn, otherFn } from 'myModule'; 

describe('test category',() => { 
    it('tests something about testFn',() => { 
    // I want to mock "otherFn" here but can't reassign 
    // a.k.a. can't do otherFn = jest.fn() 
    }); 
}); 

Любая помощь/понимание ценится.

+1

Я бы не сделать это , Издевательство вообще не то, что вы хотите сделать в любом случае. И если вам нужно что-то издеваться (из-за вызова сервера/etc.), Вы должны просто извлечь 'otherFn' в отдельный модуль и издеваться над этим. – kentcdodds

+0

Я также тестирую с использованием того же подхода @jrubins. Тестирование поведения 'function A', которое вызывает' функцию B', но я не хочу выполнять реальную реализацию 'функции B', потому что я хочу просто проверить логику, реализованную в' function A' – jplaza

+2

@kentcdodds, не могли бы вы пояснить что вы подразумеваете под «Mocking, как правило, вы не хотите делать в любом случае»? Это кажется довольно широким (чрезмерно широким?) Утверждением, поскольку насмехается, конечно, что-то, что часто используется, по-видимому, для (по крайней мере некоторых) веских причин. Итак, вы, возможно, ссылаетесь на то, почему насмешка не может быть хорошей, или вы действительно имеете в виду вообще? –

ответ

7

Переданный код не позволит babel извлекать привязку, на которую ссылается otherFn(). Если вы используете функцию expession, вы сможете достичь издевательств otherFn().

// myModule.js 
exports.otherFn =() => { 
    console.log('do something'); 
} 

exports.testFn =() => { 
    exports.otherFn(); 

    // do other things 
} 

 

// myModule.test.js 
import m from '../myModule'; 

m.otherFn = jest.fn(); 

Но @kentcdodds, упомянутых в предыдущем комментарии, вы, вероятно, не хотели бы, чтобы дразнить otherFn(). Скорее просто напишите новую спецификацию для otherFn() и издевайтесь над любыми необходимыми вызовами, которые она делает.

Так, например, если otherFn() делает запрос HTTP ...

// myModule.js 
exports.otherFn =() => { 
    http.get('http://some-api.com', (res) => { 
    // handle stuff 
    }); 
}; 

Здесь вы хотели бы издеваться http.get и обновить свои утверждения на основе ваших издевались реализации.

// myModule.test.js 
jest.mock('http',() => ({ 
    get: jest.fn(() => { 
    console.log('test'); 
    }), 
})); 
+0

Что делать, если otherFn и testFn используются несколькими другими модулями?вам нужно настроить http mock во всех тестовых файлах, которые используют (хотя и глубокий стек) эти 2 модуля? Кроме того, если у вас уже есть тест для testFn, почему бы не заглушить testFn напрямую, а не http в модулях, использующих testFn? – rickmed

7
import m from '../myModule'; 

не работает для меня, я использовал:

import * as m from '../myModule'; 

m.otherFn = jest.fn(); 
+0

Как бы вы восстановили исходную функциональность otherFn после теста, чтобы он не мешал другим TestS? – Aequitas

0

я смог издеваться именованный импорта, как это:

import { fn } from 'module'; 

jest.mock('module'); 

// when necessary, you can fake implementation like this 
// or else, it will just spy your function 
// fn.mockImplementation(() => { /* fake implementation */ }); 

describe('suite',() => { 
    test('unit',() => { 
     /* 
     * use case implementation 
     * 
     */ 

     expect(fn).toHaveBeenCalledTimes(1); 
    }); 
}); 
Смежные вопросы