Jest.fn - 使用jest.mock时返回值返回undefined

时间:2017-09-26 16:32:41

标签: jestjs

我有以下文件我正在尝试编写单元测试:

import { document } from '../../globals';
const Overlay = () => {
  console.log(document.getElementsByTagName()); // this outputs 'undefined'
};

我正在努力模拟getElementsByTagName函数。我的测试看起来像这样..

import { document } from '../../globals';
jest.mock('../../globals', () => ({
  document: {
    getElementsByTagName: jest.fn().mockReturnValue('foo')
  }
}));
console.log(document.getElementsByTagName()); // this outputs 'foo'

但遗憾的是,顶层文件中的console.log始终输出undefined。它可以看到文档对象和getElementsByTagName模拟,但返回值始终是未定义的。

如果我是console.log(document.getElementsByTagName),我会得到以下内容:

{ getElementsByTagName:
   { [Function: mockConstructor]
     _isMockFunction: true,
     getMockImplementation: [Function],
     mock: [Getter/Setter],
     mockClear: [Function],
     mockReset: [Function],
     mockReturnValueOnce: [Function],
     mockReturnValue: [Function],
     mockImplementationOnce: [Function],
     mockImplementation: [Function],
     mockReturnThis: [Function],
     mockRestore: [Function] },
}

但如果我在另一个文件中做同样的事情,我会得到这个:

function () {
  return fn.apply(this, arguments);
}

我怀疑是jest.mock将jest.fn模拟包装在另一个函数中..任何想法?

2 个答案:

答案 0 :(得分:0)

对我有用。

例如

index.ts

import { document } from './globals';

export const Overlay = () => {
  console.log(document.getElementsByTagName());
};

globals.ts

export const document = {
  getElementsByTagName() {
    return 'real element';
  },
};

index.test.ts

import { Overlay } from './';

jest.mock('./globals', () => ({
  document: {
    getElementsByTagName: jest.fn().mockReturnValue('foo'),
  },
}));

describe('46431638', () => {
  it('should mock and pass', () => {
    jest.spyOn(console, 'log');
    Overlay();
    expect(console.log).toBeCalledWith('foo');
  });
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/46431638/index.test.ts
  46431638
    ✓ should mock and pass (24ms)

  console.log node_modules/jest-mock/build/index.js:860
    foo

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 index.ts |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        6.601s, estimated 13s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/46431638

答案 1 :(得分:0)

分配后尝试使用.mockReturnValue()

我遇到了相同的行为,并在分配后通过调用mockFn.mockReturnValue(value)找到了成功。

例如:

import { document } from '../../globals.js'

jest.mock('../../globals.js', () => ({
  document: {
    getElementsByTagName: jest.fn()
  }
}))

document.getElementsByTagName.mockReturnValue('foo')

console.log(document.getElementsByTagName()); // this outputs 'foo'

我在玩笑文档中看到了这两种模式。

我想知道后一种情况是否需要其他交互方式来对模拟的返回值进行断言,但是我还没有弄清楚。我似乎无法使用spyOn模式suggested in another answer here复制成功。