Core Concepts

Understanding Key Concepts

Before you start mocking, it's important to understand a few concepts that will make using this package easier. Please make sure you understand these concepts.


Mock TypeORM Calls

Here’s how you can mock TypeORM calls. Use the following snippet:

import { MockTypeORM } from 'mock-typeorm'

test('abc', () => {
  new MockTypeORM()
})

By just doing this, you prevent any interaction with your database. This is the magic of mocking.

Reset or Restore Mock State

After each test, you need to clear the mock state so that other tests cannot use the mock state of previous tests. Otherwise, you’ll get some strange results. To reset the state, you have different methods:

Method 1: Using Hooks

import Sinon from 'sinon'
import { MockTypeORM } from 'mock-typeorm'
import { afterEach, beforeEach, describe, expect, it } from 'vitest'

describe('tests suite', () => {
  let typeorm: MockTypeORM

  beforeEach(() => {
    typeorm = new MockTypeORM()
  })

  afterEach(() => {
    typeorm.restore()
    // you can also do this instead - Sinon.restore()
    // Sinon.restore();
  })

  it('first test', async () => {
    const mockUsers = ['user']
    typeorm.onMock('User').toReturn(mockUsers, 'find')

    const users = await dataSource.getRepository(User).find()

    expect(users).toEqual(mockUsers)
  })

  it('second test', async () => {
    const mockUsers = []
    typeorm.onMock('User').toReturn(mockUsers, 'find')

    const users = await dataSource.getRepository(User).find()

    expect(users).toEqual(mockUsers)
  })
})

In this approach, using hooks provided by Vitest (or similar hooks from other testing libraries), we create a new MockTypeORM object in the beforeEach hook and restore TypeORM to its original state in the afterEach hook.

Method 2: Single Instance

import Sinon from 'sinon'
import { MockTypeORM } from 'mock-typeorm'
import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest'

describe('tests suite', () => {
  let typeorm: MockTypeORM

  beforeAll(() => {
    typeorm = new MockTypeORM()
  })

  afterEach(() => {
    typeorm.resetAll()
  })

  afterAll(() => {
    typeorm.restore()
  })

  it('first test', async () => {
    const mockUsers = ['user']
    typeorm.onMock('User').toReturn(mockUsers, 'find')

    const users = await dataSource.getRepository(User).find()

    expect(users).toEqual(mockUsers)
  })

  it('second test', async () => {
    const mockUsers = []
    typeorm.onMock('User').toReturn(mockUsers, 'find')

    const users = await dataSource.getRepository(User).find()

    expect(users).toEqual(mockUsers)
  })
})

In this approach, we create a MockTypeORM instance once before all tests start and reset the mock state after each test. After all tests, we restore TypeORM to its original behavior.

Which Method to Choose

Method 2 is preferable because we create only one mock instance and use the same instance throughout the test file. This speeds up the unit tests because we wrap our spies around TypeORM only once. Method 1 can be problematic if you have a large number of unit tests and limited CPU/RAM resources.

Previous
Installation