felixmosh / knex-mock-client

A mock client for knex which allows you to write unit tests with DB interactions
MIT License
53 stars 8 forks source link

Cannot read properties of undefined (reading 'apply') #12

Closed luizpmonteiro8 closed 2 years ago

luizpmonteiro8 commented 2 years ago

As you can see I made the code a little different, but it works, it shows this error, what can I do to fix it? thanks

I didn't use this

jest.mock('../common/db-setup', () => {
  return {
    db: knex({ client: MockClient })
  };
});

save

const save = (job) => {
    delete job.id;

    return app
      .db('job')
      .insert(job)
      .returning('id')
      .catch((e) => {
        app.api.services.throwError(e);
      });
  };

test.js

const app = require('../index');
const db = require('../config/db');
const config = require('../knexfile.js');
const error = require('../api/services/throwError');
const { getTracker } = require('knex-mock-client');

app.db = db;
app.api = () => {};
app.api.services = () => {};
app.api.services.throwError = error;

const service = require('../api/services/jobService')(app);

jest.mock('../knexfile', () => {
  return {
    client: require('knex-mock-client').MockClient,
  };
});

describe('Test the root path', () => {
  let tracker;

  beforeAll(() => {
    tracker = getTracker();
  });

  afterEach(() => {
    tracker.reset();
  });

  test('It should response the GET method', async () => {
    tracker.on.insert('job').response({ id: 1 });
    const result = await service.save({ name: 'Servente' });
    expect(result).toStrictEqual({ id: 5 });
  });
});

error

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

      at SchemaCompiler.toSQL (node_modules/knex/lib/schema/compiler.js:97:26)
      at SchemaBuilder.toSQL (node_modules/knex/lib/schema/builder.js:35:45)
      at ensureConnectionCallback (node_modules/knex/lib/execution/internal/ensure-connection-callback.js:4:30)
      at Runner.ensureConnection (node_modules/knex/lib/execution/runner.js:307:20)
      at Runner.run (node_modules/knex/lib/execution/runner.js:30:19)
      at listCompleted (node_modules/knex/lib/migrations/migrate/migration-list-resolver.js:12:3)
          at async Promise.all (index 1)
      at Migrator.latest (node_modules/knex/lib/migrations/migrate/Migrator.js:63:29)
expect(received).toStrictEqual(expected) // deep equality

    - Expected  - 1
    + Received  + 1

      Object {
    -   "id": 5,
    +   "id": 1,
      }

      32 |     tracker.on.insert('job').response({ id: 1 });
      33 |     const result = await service.save({ name: 'Servente' });
    > 34 |     expect(result).toStrictEqual({ id: 5 });
         |                    ^
      35 |   });
      36 | });
      37 |

      at Object.<anonymous> (test/jobService.test.js:34:20)
felixmosh commented 2 years ago

Thank you for reporting this issue,

It depends on the code that is inside knexfile, can you share it? I guess that knexfile file should return a knex instance not the mock.

Instead of

jest.mock('../knexfile', () => {
  return {
    client: require('knex-mock-client').MockClient,
  };
});

It the mock should be

jest.mock('../knexfile', () => {
  return knex({ client: MockClient });
  // ------^ this is a real instance of knex with a mock client (instead of mysql client or any other DB client)
});
luizpmonteiro8 commented 2 years ago

i make this,

jest.mock('../config/db', () => {
  const { Model } = require('objection');
  const knex = require('knex')({ client: require('knex-mock-client').MockClient });

  // knex.migrate.latest([{ client: require('knex-mock-client').MockClient }]);
  Model.knex(knex);

  module.exports = knex;
  return knex;
});

remove migrate and works, thanks a lot for the help!