jakearchibald / idb

IndexedDB, but with promises
https://www.npmjs.com/package/idb
ISC License
6.39k stars 361 forks source link

How to test with Jest? #165

Closed geoidesic closed 4 years ago

geoidesic commented 4 years ago

Hi,

I'm trying to figure out how to write tests using this library. I looked at fake-indexeddb/auto and while this seems to work partly I end up with an instance of idb that doesn't have a put method. I looked at the mocha tests included in the lib... but I didn't understand them – they seem to have been written without mocking IndexedDB at all?

Here's what I tried:

import actions from "../actions";
import IndexedDB from "fake-indexeddb/auto";
import { openDB } from "idb/with-async-ittr-cjs"; 

class DbService {
  instance = void 0;
  async initialize() {
    this.instance = await openDB("MNR", 2, {
    ...
    })
  }
};
const db = new DbService();
db.initialize();
test("IDB_resetBusy to call put", async () => {
    await db.initialize();
    db.instance.put = jest.fn();
    await actions.IDB_resetBusy("blah");
    expect(db.instance.put).toHaveBeenCalledTimes(1);
  });

I get the error:

TypeError: Cannot read property 'put' of undefined
jakearchibald commented 4 years ago

I deliberately don't test with a mock, as it's more important for me to see how it works with actual indexeddb.

Closing this, as it isn't an issue with the library, but I'm happy to continue answering questions etc.

geoidesic commented 4 years ago

Thank you Jake. What I'm not understanding is that IndexedDB only exists in browser. Unit tests don't have a browser, thus do not have IndexedDB. So how is it possible to test without a mock?

jakearchibald commented 4 years ago

I'm not sure. Fwiw I tend to only write integration tests for things that involve indexeddb, because it's more important for me to test real indexeddb than a mock.

geoidesic commented 4 years ago

I understand that. I just don't understand how you are able to test real IndexedDB as it only exists in browsers and afaik mocha doesn't provide that capability, so IndexedDB should evaluate to undefined... it does when I try it and is the reason for the existence of libraries such as fake-indexeddb/auto.

jakearchibald commented 4 years ago

Mocha runs in the browser

zquancai commented 4 years ago

Thank you Jake. What I'm not understanding is that IndexedDB only exists in browser. Unit tests don't have a browser, thus do not have IndexedDB. So how is it possible to test without a mock?

I think you can use karma to run in the browser.

taxilian commented 3 years ago

While it would be good to do real tests with karma or similar, there are definitely advantages to testing with something like jest or mocha as well using mocks. I have unit tests working with jest, fake-indexeddb, and idb by doing the following:

module.exports = {
  preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
  transform: {
    '^.+\\.vue$': 'vue-jest'
  },
  setupFiles: [
    "fake-indexeddb/auto"
  ]
}

Beyond that things Just Work so far. Remember it's a mock so you should do real integration tests as well, but for checking application logic this runs much faster than something requiring a browser, even a headless one.