Jest Unit Class with Dependencies

906 views Asked by At

I'm trying to unit test this class that has a dependency of AppDB and createStudy that I need to mock. To get started I'm attempting to unit test the simple method startLoadingData which happens to be a MobX action

import { observable, action } from 'mobx'
import { Intent } from '@blueprintjs/core'
import { createStudy } from '../database/DatabaseInit'
import { AppDB } from '../database/Database'


export default class UIStore {
  // ui state
  // booleans indicating open/close state of modals
  @observable createDialogue
  @observable importDialogue
  @observable revisionsDialogue
  @observable runDialogue
  // boolean indicating loading or waiting for async action
  @observable loadingData
  // array indicating navigation
  @observable breadcrumbs
  @observable processingMessages

  constructor(rootStore) {
    this.rootStore = rootStore
    this.breadcrumbs = []
    this.importDialogue = false
    this.createDialogue = false
    this.revisionsDialogue = false
    this.runDialogue = false
    // boolean to display loading blur on table that displays data
    this.loadingData = false
    // processing messages for import and other async loads
    this.processingMessages = []
  }
  @action startLoadingData() {
    this.loadingData = true
  }
}

My test file below is getting nowhere because there's an error being thrown related to a separate dependency of sqlite3 in the AppDB and createStudy imports. My understanding is that if I mock those two dependencies that I can avoid the error because they'll be mocked and not real implementations trying to use sqlite3.

// UIStore domain store unit test
// import * as Database from '../../app/database/Database'
// import * as DatabaseInit from '../../app/database/DatabaseInit'
import UIStore from '../../app/stores/UIStore'


describe('UIStore', () => {
  beforeEach(() => {
    // jest.spyOn(Database, 'AppDB').andReturn('mockAppDB')
    // jest.spyOn(DatabaseInit, 'createStudy').andReturn('createStudy')
    jest.mock('../../app/database/Database')
    // jest.mock('DatabaseInit')
  })
  it('starts loading data', () => {
    const testUIStore = new UIStore(this)
    testUIStore.startLoadingData()
    expect(testUIStore.loadingData).toBe(true)
  })
})

As you can see, trying a bunch of things, but I don't seem to be getting anywhere. I've read about manual mocks, and thought that might be the case so I made a manual mock of Database but not even sure if I'm doing that correctly.

const Database = jest.genMockFromModule('../Database.js')

module.exports = Database

I dont think this matters, but it might be worth noting that AppDB is a ES6 class and createStudy is a method.

1

There are 1 answers

2
Andrei CACIO On BEST ANSWER

Jest should auto mock modules from node_modules if you create a __mocks__ folder in your root project folder and create in that folder mocks for the modules you want auto mocked. By auto mock I mean that when writing a test and Jest detects that folder it will automatically load the mock instead of the original module. This also applies to dependencies of dependencies.

So in your case I would try to create a sqlite3 like so:

/project
|
-> __mocks__
|  |
|  -> sqlite3/index.js <- export mocked functions
|
-> node_modules

At least this is how I deal with libraries in my Jest tests.

Hope this helps.