Logo

dev-resources.site

for different kinds of informations.

Mock TypeORM Package

Published at
6/26/2024
Categories
typeorm
mocking
typescript
testing
Author
jazimabbas
Author
10 person written this
jazimabbas
open
Mock TypeORM Package

References

  1. Mock TypeORM Package
  2. Mock TypeORM Package Documentation

In the last couple of months, I have been working extensively with TypeORM and built many projects using this ORM. Setting up a test database for my unit tests was quite challenging. To overcome this, I mocked TypeORM methods to avoid interacting with a real database. However, I found myself copying the same mock code into every new project repeatedly.

To streamline this process and help others facing the same issue, I decided to create a package. Initially, I mocked all the TypeORM code using Vitest, but that only worked in the Vitest environment. Since many developers use different testing frameworks such as Jest, Mocha, etc., I needed a more versatile solution. Hence, I used Sinon for mocking TypeORM, which is compatible with various testing frameworks. Although Sinon is excellent, I still have a soft spot for Vitest.

Installation

This package is built using TypeScript, so you’ll get type safety out of the box. I have also added thorough unit tests, which you can refer to for better understanding and reference.

To install this package, use the following command:

npm install --save-dev mock-typeorm sinon @types/sinon
Enter fullscreen mode Exit fullscreen mode

That’s pretty much it! Now you can use this package to mock your TypeORM calls. Note that Sinon is added as a peer dependency, so you need to install it as well.

Key Concepts

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

import { MockTypeORM } from 'mock-typeorm'

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

Enter fullscreen mode Exit fullscreen mode

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: Create an instance for each test

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)
  })
})
Enter fullscreen mode Exit fullscreen mode

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)
  })
})
Enter fullscreen mode Exit fullscreen mode

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.

Mocking - Fun Stuff

Now that you understand how mocking works and how to restore it to its original behavior, let's see how to mock actual methods like find(), findOne(), save(), etc.

Example

describe('test suites', () => {
  it('test', async () => {
    const typeorm = new MockTypeORM()
    typeorm.onMock(User).toReturn(['user'], 'find')

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

    expect(users).toEqual(['user'])
  })
})
Enter fullscreen mode Exit fullscreen mode

Helper Functions

  • onMock()
  • resetAll()
  • restore()

onMock()

onMock() accepts a repository class or string (repository name). This is useful when using EntitySchema in JavaScript.

const typeorm = new MockTypeORM()
typeorm.onMock(User) // repository class
typeorm.onMock('User') // repository name as string
Enter fullscreen mode Exit fullscreen mode

onMock() returns this to allow method chaining:

typeorm.onMock(User).toReturn([], 'find').toReturn({ id: '1' }, 'findOne')
Enter fullscreen mode Exit fullscreen mode

reset()

onMock() also returns a reset() method to reset mock data:

describe('test suites', () => {
  it('test', async () => {
    const typeorm = new MockTypeORM()
    typeorm.onMock(User).toReturn(['user'], 'find').reset('find')

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

    expect(users).toEqual({})
  })
})
Enter fullscreen mode Exit fullscreen mode

As you can see, I reset the mock data for the find method that we set using the toReturn() function. So when the find() method is called and no mock data is found for that method, it will return {} by default. That’s what we are expecting in our test assertion, meaning we have successfully reset the find method.

To reset everything at the repository level:

describe('test suites', () => {
  it('test', async () => {
    const typeorm = new MockTypeORM()
    typeorm
      .onMock(User)
      .toReturn(['user'], 'find')
      .toReturn({ id: '1' }, 'findOne')
      .reset()

    const userRepo = dataSource.getRepository(User)
    const users = await userRepo.find()
    const user = await userRepo.findOne({})

    expect(users).toEqual({})
    expect(user).toEqual({})
  })
})
Enter fullscreen mode Exit fullscreen mode

If you find this package useful please stare this my github repository and share with other developers.

Buy Me A Coffee

So if you enjoy my work and found it useful, consider buying me a coffee! I would really appreciate it.

mocking Article's
30 articles in total
Favicon
4. Testing (async) searchParams with Jest in Next 15
Favicon
Enhancing API Workflows: A Comprehensive Guide to Mock Responses and Efficient Testing
Favicon
Dummy API for Testing: How to Use It vs Mocking
Favicon
How Better Mocking Makes Building APIs Smoother and Speed Up Development
Favicon
A Step-by-Step Guide to API Creation and Mocking for Faster Development
Favicon
How I've been trying to improve mocking with Zod
Favicon
How to Set Up a Mock Server
Favicon
Best API Mocking Platforms in 2024
Favicon
Server Side Mocking for Playwright in NextJS (App Router) using Mock Service Worker
Favicon
How Mocking Against a Public API Endpoints within Blackbird Gets your API in Production Faster
Favicon
10 Best API Mocking Tools (2025 Review)
Favicon
Introduction to Jest: Unit Testing, Mocking, and Asynchronous Code
Favicon
Mocking an AI Chatbot API with Blackbird
Favicon
Incredibly Useful WireMock with IntelliJ IDEA
Favicon
Simplifying Mocking APIs for Faster Development: Basic & Advanced Techniques
Favicon
The Case Against Mocking Libraries
Favicon
Mocking an AI Chatbot API with Blackbird
Favicon
API Mocking: A Comprehensive Guide
Favicon
Mock TypeORM Package
Favicon
Level Up Your Node.js Testing with Native Test Runner and Mocks: A BigQuery Example
Favicon
Unit Tests for Frontend Developers [Part 2]
Favicon
Revamped Mock-API.net: Simplifying API Mocking for Developers
Favicon
Mocking with Sinon.js: A Comprehensive Guide
Favicon
Streamline Development with Effective API Mocking
Favicon
API mocking with Mock Service Worker + Vue.js
Favicon
Partial: how NOT to mock the whole world
Favicon
Introducing Mockallan: Testing with API-Level Stubs and Mocks
Favicon
Como fazer Deploy de uma api com Json-Server
Favicon
What's the real ROI of writing Mocks?
Favicon
Unleashing GraphQL Type-Based Mocking

Featured ones: