te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - Why is Jest still requiring a mocked module? - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Why is Jest still requiring a mocked module? - Stack Overflow

programmeradmin3浏览0评论

I am mocking a module using Jest because it contains code that shouldn't run in the test. However I can see from the output that code in the module is being run.

// foo.js
console.log('Hello')

// test.js
jest.mock('./foo')
const foo = require('./foo')

test.todo('write some tests')

Console output

PASS  test.js
  ✎ todo 1 test

console.log foo.js:1
Hello

What's up with that?

I am mocking a module using Jest because it contains code that shouldn't run in the test. However I can see from the output that code in the module is being run.

// foo.js
console.log('Hello')

// test.js
jest.mock('./foo')
const foo = require('./foo')

test.todo('write some tests')

Console output

PASS  test.js
  ✎ todo 1 test

console.log foo.js:1
Hello

What's up with that?

Share Improve this question asked Apr 11, 2019 at 12:14 TamlynTamlyn 23.6k13 gold badges119 silver badges137 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 20

This has tripped me up a couple of times.

If you don't provide a mock implementation to jest.mock it will return an object which mirrors the exports of the mocked module but with every function replaced with a mock jest.fn(). This is pretty neat as it is often what you want. But in order to determine the exports of the module, it must first require it. This is what is causing the console.log to be run.

Two possible solutions:

  • Don't run code in the top level of the module: instead export a function which runs the code.
  • Provide your own mock implementation so it doesn't need to introspect the module jest.mock('./foo', () => {})

Jest still executes automocked modules because that's how automock works.

Instead of static code analysis, it attempts to execute module script and analyze result object properties.

The result object properties (usually, functions) are used as a 'blueprint' to create mock module with same properties but mocked values.

Have a look on Jest's mock generation code:

_generateMock(from, moduleName) {
const modulePath =
  this._resolver.resolveStubModuleName(from, moduleName) ||
  this._resolveModule(from, moduleName, {
    conditions: this.cjsConditions
  });

if (!this._mockMetaDataCache.has(modulePath)) {
  // This allows us to handle circular dependencies while generating an
  // automock
  this._mockMetaDataCache.set(
    modulePath,
    this._moduleMocker.getMetadata({}) || {}
  ); // In order to avoid it being possible for automocking to potentially
  // cause side-effects within the module environment, we need to execute
  // the module in isolation. This could cause issues if the module being
  // mocked has calls into side-effectful APIs on another module.

  const origMockRegistry = this._mockRegistry;
  const origModuleRegistry = this._moduleRegistry;
  this._mockRegistry = new Map();
  this._moduleRegistry = new Map();
  const moduleExports = this.requireModule(from, moduleName); // Restore the "real" module/mock registries

  this._mockRegistry = origMockRegistry;
  this._moduleRegistry = origModuleRegistry;

  const mockMetadata = this._moduleMocker.getMetadata(moduleExports);

  if (mockMetadata == null) {
    throw new Error(
      `Failed to get mock metadata: ${modulePath}\n\n` +
        'See: https://jestjs.io/docs/manual-mocks#content'
    );
  }

  this._mockMetaDataCache.set(modulePath, mockMetadata);
}

In this code, the 'real' module code will be executed in line

const moduleExports = this.requireModule(from, moduleName);

And as mentioned in Tamlyn's answer, it can be avoided by avoiding automock, via manual mock implementation.

发布评论

评论列表(0)

  1. 暂无评论