【问题标题】:Jest mocking a module with module pattern and having unique functionality on each testJest 使用模块模式模拟模块并在每个测试中具有独特的功能
【发布时间】:2022-01-05 00:02:28
【问题描述】:

我无法从我拥有的这个模块模式设置 (MyConnection.js) 中进行独特的搜索实现 - 这与我所拥有的类似:

// MyConnection.js
const MyConnection = () => {
  const search = async (q) => {
    //...some functionality
  };
  return {
    search,
  };
};
  

//JEST TESTS
const MyConnection = require('../MyConnection')

// this works - but it sets the search implementation 
// for the whole test file I believe
jest.mock('../MyConnection', () => {
    return jest.fn(()=>{
        search: ()=> ['mocked', 'fn', 'results']
    })
})


//the jest tests - I want different 
// implementations of search in each test
describe('connection tests', ()=>{

    it('test one', ()=>{

        //Not sure if its something like this to set 'search' for each test? This doesn't work as is
        MyConnection.search.mockImplementation((q)=>{`You searched ${q}`})
    })

    it('test two', ()=>{
        MyConnection.search.mockImplementation((q)={q.length>32? 'a': 'b' }})
    })

})

如何为每个测试获得该搜索功能的唯一 Jest 模拟实现?

【问题讨论】:

    标签: javascript unit-testing jestjs


    【解决方案1】:

    您应该确保 mock MyConnection 在您的测试文件和您要测试的模块中始终返回相同的连接对象。

    MyConnection.js:

    const MyConnection = () => {
      const search = async (q) => {};
      return {
        search,
      };
    };
    
    module.exports = MyConnection;
    

    main.js:

    const MyConnection = require('./MyConnection');
    
    async function main(q) {
      const conn = MyConnection();
      return conn.search(q);
    }
    
    module.exports = main;
    

    main.test.js:

    const MyConnection = require('./MyConnection');
    const main = require('./main');
    
    jest.mock('./MyConnection', () => {
      console.log('MyConnection module gets mocked');
      const conn = { search: jest.fn() };
      return jest.fn(() => conn);
    });
    const mConn = MyConnection();
    
    describe('connection tests', () => {
      it('test one', async () => {
        mConn.search.mockImplementation((q) => {
          return `You searched ${q}`;
        });
        const actual = await main('teresa teng');
        expect(actual).toBe('You searched teresa teng');
      });
    
      it('test two', async () => {
        mConn.search.mockImplementation((q) => {
          return q.length > 32 ? 'a' : 'b';
        });
        const actual = await main('_');
        expect(actual).toBe('b');
      });
    });
    

    测试结果:

     PASS  examples/70132655/main.test.js (10.454 s)
      connection tests
        ✓ test one (2 ms)
        ✓ test two (1 ms)
    
      console.log
        MyConnection module gets mocked
    
          at examples/70132655/main.test.js:5:11
    
    Test Suites: 1 passed, 1 total
    Tests:       2 passed, 2 total
    Snapshots:   0 total
    Time:        10.903 s
    

    不能这样嘲笑它:

    jest.mock('./MyConnection', () => {
      console.log('MyConnection module gets mocked');
      return jest.fn(() => { search: jest.fn() });
    });
    

    为什么?因为每次在测试文件或者要测试的文件中调用MyConnection()函数。它将返回一个新的模拟对象({ search: jest.fn() }),被测文件和测试用例中的模拟对象不一样。

    【讨论】:

      猜你喜欢
      • 2019-07-16
      • 2019-08-28
      • 1970-01-01
      • 1970-01-01
      • 2021-08-27
      • 1970-01-01
      • 1970-01-01
      • 2018-01-18
      • 2021-06-27
      相关资源
      最近更新 更多