function mock ({ bump, changelog, execFile, fs, pkg, tags } = {}) {
  mockery.enable({ warnOnUnregistered: false, useCleanCache: true })

  mockery.registerMock('conventional-recommended-bump', function (opt, cb) {
    if (typeof bump === 'function') bump(opt, cb)
    else if (bump instanceof Error) cb(bump)
    else cb(null, bump ? { releaseType: bump } : {})
  })

  if (!Array.isArray(changelog)) changelog = [changelog]
  mockery.registerMock(
    'conventional-changelog',
    (opt) =>
      new Readable({
        read (_size) {
          const next = changelog.shift()
          if (next instanceof Error) {
            this.destroy(next)
          } else if (typeof next === 'function') {
            this.push(next(opt))
          } else {
            this.push(next ? Buffer.from(next, 'utf8') : null)
          }
        }
      })
  )

  mockery.registerMock('git-semver-tags', function (cb) {
    if (tags instanceof Error) cb(tags)
    else cb(null, tags | [])
  })

  if (typeof execFile === 'function') {
    // called from commit & tag lifecycle methods
    mockery.registerMock('../run-execFile', execFile)
  }

  // needs to be set after mockery, but before mock-fs
  standardVersion = require('../index')

  fs = Object.assign({}, fs)
  if (pkg) {
    fs['package.json'] = JSON.stringify(pkg)
  } else if (pkg === undefined && !fs['package.json']) {
    fs['package.json'] = JSON.stringify({ version: '1.0.0' })
  }
  mockFS(fs)

  stdMocks.use()
  return () => stdMocks.flush()
}
Mock external conventional-changelog modules

Mocks should be unregistered in test cleanup by calling unmock()

bump?: 'major' | 'minor' | 'patch' | Error | (opt, cb) => { cb(err) | cb(null, { releaseType }) }
changelog?: string | Error | Array<string | Error | (opt) => string | null>
execFile?: ({ dryRun, silent }, cmd, cmdArgs) => Promise<string>
fs?: { [string]: string | Buffer | any }
pkg?: { [string]: any }
tags?: string[] | Error