mock-knex
mock-knex copied to clipboard
TypeError: Cannot read properties of undefined (reading 'response')
trafficstars
I'm getting a TypeError: Cannot read properties of undefined (reading 'response') in your code.
System under test
Source code of db.js file:
import knex from './knex.js' // <-- returns a knex() object
export class Database {
constructor() {
this.db = knex
// Check if we have a connection?
this.db.raw('SELECT 1').then(async () => {
await this.initialize()
}).catch((error) => {
console.error(error)
})
}
More source code... My knex.js file:
import knex from 'knex'
const DB_CONNECTION = process.env.PG_CONNECTION_STRING || 'postgresql://[email protected]:5433/gh_automate' // Fallback to local development
/**
* Knex object using pg-native (PostgreSQL client)
*/
export default knex({
client: 'pgnative',
connection: DB_CONNECTION,
useNullAsDefault: true,
})
Test
Test code (with Mocha):
import mockDb from 'mock-knex'
import knex from '../src/knex.js'
import { Database } from '../src/db.js'
describe('Database', function () {
describe('Good-weather', function () {
let database
beforeEach((done) => {
mockDb.mock(knex)
database = new Database()
done()
})
})
})
Error
The error is because I use a .catch((error) => {} on the this.db.raw Promise in db.js file. Which is just valid, no issues in running all this code when not unit testing...
However when using mock-knex (and the knex objected is mocked) I now get:
TypeError: Cannot read properties of undefined (reading 'response')
at Client_PgNative.processResponse (/home/user/some_foldernode_modules/knex/lib/dialects/postgres/index.js:239:22)
at /home/user/some_foldernode_modules/knex/lib/execution/runner.js:151:35
at tryCatcher (/home/user/some_foldernode_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/home/user/some_foldernode_modules/bluebird/js/release/promise.js:547:31)
at Promise._settlePromise (/home/user/some_foldernode_modules/bluebird/js/release/promise.js:604:18)
at Promise._settlePromise0 (/home/user/some_foldernode_modules/bluebird/js/release/promise.js:649:10)
at Promise._settlePromises (/home/user/some_foldernode_modules/bluebird/js/release/promise.js:729:18)
at _drainQueueStep (/home/user/some_foldernode_modules/bluebird/js/release/async.js:93:12)
at _drainQueue (/home/user/some_foldernode_modules/bluebird/js/release/async.js:86:9)
at Async._drainQueues (/home/user/some_foldernode_modules/bluebird/js/release/async.js:102:5)
at Async.drainQueues (/home/user/some_foldernode_modules/bluebird/js/release/async.js:15:14)
at process.processImmediate (node:internal/timers:478:21)
Or .. I just mock the knex object incorrectly .. but I don't get it!? Do I something wrong maybe?
Or is raw not correctly mocked by mock-knex??
Trying to debug it myself. Going to: node_modules/knex/lib/dialects/postgres/index.js
// Ensures the response is returned in the same format as other clients.
processResponse(obj, runner) {
const resp = obj.response; // <--- this line is failing, but only when i use mock-knex. Are you calling this method?
if (obj.output) return obj.output.call(runner, resp);
if (obj.method === 'raw') return resp;
const { returning } = obj;
if (resp.command === 'SELECT') {
if (obj.method === 'first') return resp.rows[0];
if (obj.method === 'pluck') return map(resp.rows, obj.pluck);
return resp.rows;
}