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

conn.beginTransaction is not a function when dialect is mssql #25

Closed cldsnchz closed 2 years ago

cldsnchz commented 2 years ago

Hi, I'm getting conn.beginTransaction is not a function when the configuration is { client: MockClient, dialect: "mssql" } and test code that opens a transaction.

The error is generated in transaction.js of the the mssql dialect that call conn.beginTransaction (and other conn functions) but the connection generated by the mock doesn't have it.

felixmosh commented 2 years ago

Can you provide a code snippet of your query and the test itself?

cldsnchz commented 2 years ago

Here is the test and the function to test. The function is just an update inside a transaction.

import knex from "knex";
import { getTracker, MockClient, Tracker } from "knex-mock-client";

import * as knexBuilder from "./knex-builder";

const knexClientMock = knex({ client: MockClient, dialect: "mssql" });
jest.spyOn(knexBuilder, "build").mockReturnValue(knexClientMock);

describe("knex-mock-client", () => {
  let tracker: Tracker;

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

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

  it("update", async () => {
    tracker.on.update("table").responseOnce(1);
    const updates = await update();
    expect(updates).toEqual(1);
  });
});

export async function update(): Promise<number> {
  const knex = knexBuilder.build({ client: "mssql" });
  return knex.transaction((tx) => {
    return tx("table").update({ value: "test" }).where({ id: 1 });
  });
}

knex-builder is nothing but:

import knex, { Knex } from "knex";

export function build(config: Knex.Config): Knex {
  return knex(config);
}

When I run this test I get:

 FAIL  test/knex-client-mock.spec.ts
  knex-mock-client
    ✕ update (2 ms)

  ● knex-mock-client › update

    TypeError: conn.beginTransaction is not a function

      at node_modules/knex/lib/dialects/mssql/transaction.js:9:12
      at Transaction_MSSQL.begin (node_modules/knex/lib/dialects/mssql/transaction.js:8:12)
      at node_modules/knex/lib/execution/transaction.js:203:16
      at Transaction_MSSQL.acquireConnection (node_modules/knex/lib/execution/transaction.js:254:20)
felixmosh commented 2 years ago

Thanx, let me check it.

Anyway, you don't need the spyOn at all.

import knex from https://github.com/knex/knex;
import { getTracker, MockClient, Tracker } from https://github.com/felixmosh/knex-mock-client;

const knexClientMock = knex({ client: MockClient, dialect: "mssql" });

describe("knex-mock-client", () => {
  let tracker: Tracker;

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

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

  it("update", async () => {
    tracker.on.update("table").responseOnce(1);
    const updates = await update();
    expect(updates).toEqual(1);
  });
});

export async function update(): Promise<number> {
  return knexClientMock.transaction((tx) => {
    return tx("table").update({ value: "test" }).where({ id: 1 });
  });
}
felixmosh commented 2 years ago

Thank you for reporting this issue, it should be fixed in v1.8.4

cldsnchz commented 2 years ago

Awesome! I tested it with my tests. worked fine. thanks!.