16
votes

When creating unit tests for typeorm, I want to mock my connection to the database so that I can run unit tests without actually ever connecting to the DB (a good thing!)

I see places where people have mocked typeorm's repositories using testdouble (which I am also using), but I am trying to do this with getManager and am having an issue figuring out how to make it work.

Here's an example. I have a class that, in the constructor, creates an EntityManager by using getManager() for a connection called 'test':

export class TestClass {
    constructor() {
        const test: EntityManager = getManager('test');
    }
}

Now I want to test that I can simply create this class. Here's a sample (using mocha, chai, and testdouble):

describe('data transformer tests', () => {
    it('can create the test class', () => {

        // somehow mock getManager here

        const testClass: TestClass = new TestClass();
        chai.expect(testClass, 'could not create TestClass').to.not.be.null;
    });
});

When I try this, I get this error message from typeorm:

ConnectionNotFoundError: Connection "test" was not found.

Here are some of the things I've tried to mock getManager:

td.func(getManager)

same error as above.

td.when(getManager).thenReturn(td.object('EntityMananger'));

gets the message:

Error: testdouble.js - td.when - No test double invocation call detected for `when()`.

Any ideas what the magic sauce is here for mocking getManager?

1
Just to add, I never found an answer with this, and wound up using sinon for my mocks, and it worked just fine.CleverPatrick
Are you not supposed to actually make the call in td.when()? i.e "when called with x then return y"; something along those lines: td.when(getManager(x)).thenReturn(y). I think this is what the error message is saying. You need to tell TD what to return for a given function call.customcommander

1 Answers

7
votes

I tried sinon instead of testdouble. I created a small repository, which shows how you can mock database for your blazing unit-tests :)

I tried to cover all TypeORM test cases using Jest and Mocha

Example

import * as typeorm from 'typeorm'
import { createSandbox, SinonSandbox, createStubInstance } from 'sinon'
import { deepEqual } from 'assert'

class Mock {
  sandbox: SinonSandbox

  constructor(method: string | any, fakeData: any, args?: any) {
    this.sandbox = createSandbox()

    if (args) {
      this.sandbox.stub(typeorm, method).withArgs(args).returns(fakeData)
    } else {
      this.sandbox.stub(typeorm, method).returns(fakeData)
    }
  }

  close() {
    this.sandbox.restore()
  }
}

describe('mocha => typeorm => getManager', () => {
  let mock: Mock

  it('getAll method passed', async () => {
    const fakeManager = createStubInstance(typeorm.EntityManager)
    fakeManager.find.resolves([post])

    mock = new Mock('getManager', fakeManager)

    const result = await postService.getAll()
    deepEqual(result, [post])
  })

  afterEach(() => mock.close())
})