0

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.

spakmad
  • 880
  • 6
  • 15

1 Answers1

1

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.

Andrei CACIO
  • 2,101
  • 15
  • 28
  • I have implemented that file structure with the following code: `const sqlite3 = jest.genMockFromModule('sqlite3'); module.exports = sqlite3; ` Basically, there are no specific methods I need mocked, I just don't want it to look in the actual `sqlite3` node module because due to my project environment (Electron) it's incompatible with Jest (Node). However, it appears even with this mock, the actual `sqlite3` module is still being referenced. – spakmad Sep 07 '17 at 21:53
  • It appears I've solved my own problem that was originating due to the two `package.json` structure of my electron app, and that the `node_modules` in my `app` directory did not have the binding for node that was in my root directory. A simple copy of the binding removed the error I was getting, and eliminating my theory that I should simply mock the library. Sorry that the question was actually more specific than it appeared. But, I think in principal, your answer makes sense according to everything else I've read about Jest. – spakmad Sep 07 '17 at 22:39