mock-knex icon indicating copy to clipboard operation
mock-knex copied to clipboard

TypeError: Cannot read properties of undefined (reading 'response')

Open melroyvandenberg opened this issue 1 year ago • 0 comments
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;
    }

melroyvandenberg avatar Sep 26 '24 17:09 melroyvandenberg