Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unmock does not work correctly #126

Open
sl-ffx opened this issue Mar 26, 2021 · 4 comments · May be fixed by #138
Open

unmock does not work correctly #126

sl-ffx opened this issue Mar 26, 2021 · 4 comments · May be fixed by #138

Comments

@sl-ffx
Copy link

sl-ffx commented Mar 26, 2021

The unmock method does not work as expected. I would expect to have the original client working as it would never have been mocked.
After unmock the client always throw an error on executing a query:

TypeError: Cannot read property 'response' of undefined
    at Client_PG.processResponse (project/node_modules/knex/lib/dialects/postgres/index.js:247:22)
    at project/node_modules/knex/lib/runner.js:162:28
    at tryCatcher (project/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (project/node_modules/bluebird/js/release/promise.js:547:31)
    at Promise._settlePromise (project/node_modules/bluebird/js/release/promise.js:604:18)
    at Promise._settlePromise0 (project/node_modules/bluebird/js/release/promise.js:649:10)
    at Promise._settlePromises (project/node_modules/bluebird/js/release/promise.js:729:18)
    at _drainQueueStep (project/node_modules/bluebird/js/release/async.js:93:12)
    at _drainQueue (project/node_modules/bluebird/js/release/async.js:86:9)
    at Async._drainQueues (project/node_modules/bluebird/js/release/async.js:102:5)
    at Immediate.Async.drainQueues [as _onImmediate] (project/node_modules/bluebird/js/release/async.js:15:14)
    at processImmediate (internal/timers.js:461:21)

I'm using
mock-knex v0.4.9
knex v0.21.19

Here is a code example to get the error

const knex = require('knex')
const mockDb = require('mock-knex')

const db = knex({
  client: 'pg'
})

mockDb.mock(db)
mockDb.unmock(db)

db.raw('SELECT 10;')
  .then(console.log)
  .catch(console.error)

If you remove the mock and unmock lines the query works.

@sl-ffx
Copy link
Author

sl-ffx commented Mar 30, 2021

At the moment I'm using following quickfix

const mockBackup = {}
mockBackup._stream = db.client.constructor.prototype._stream
mockBackup._query = db.client.constructor.prototype._query
mockBackup.processResponse = db.client.constructor.prototype.processResponse

mockDb.mock(db)
mockDb.unmock(db)

db.client.constructor.prototype._stream = mockBackup._stream
db.client.constructor.prototype._query = mockBackup._query
db.client.constructor.prototype.processResponse = mockBackup.processResponse

@LogansUA
Copy link

LogansUA commented Aug 2, 2022

Hey, I'm having a similar issue with knex >= v0.95, but thanks to the @sl-ffx I was able to fix it.
Is there anyone who can actually fix it in mock-knex?

danthegoodman added a commit to danthegoodman/mock-knex that referenced this issue Dec 13, 2022
mock(Knex) is storing the original functions on a replacement object, 
but when being set lodash is storing it on the real object prototype.
This change modifies the replacement storage to put the function on
a renamed prototype object much like the constructor.

This allows unmock(Knex) to properly restore all mocked functions.

Fixes jbrumwell#126
@danthegoodman danthegoodman linked a pull request Dec 13, 2022 that will close this issue
@danthegoodman
Copy link

I opened an MR to fix this. If you want to monkey-patch it yourself, you can use this code (tested only with v0.4.11)

const transformer = Object.getPrototypeOf(require("mock-knex/dist/util/transformer"));
const _lodash2 = {default:require("lodash")}; // needed by the new function
const newFn = transformer._replace.toString()
  .replace(".replace('._constructor.', '.constructor.')", ".replace('._constructor.', '.constructor.').replace('._prototype.', '.prototype.')")
  .replace(".replace('.constructor.', '._constructor.')", ".replace('.constructor.', '._constructor.').replace('.prototype.', '._prototype.')");
transformer._replace = eval("(" + newFn + ")");

@barwin
Copy link

barwin commented Feb 1, 2023

We only started experiencing this error when we introduced semantic-release (versions 9 and later) as a dependency in our project. The fix in #138 solved the issue for us. Thanks @danthegoodman !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants