usePouchDB

usePouchDB

  • Docs
  • API
  • Help
  • GitHub

โ€บBasic Tutorial

Introduction

  • Quick Start
  • PouchDB and CouchDB

Basic Tutorial

  • 'Basic Tutorial: Intro'
  • Setup
  • Add the Provider
  • Add Todos
  • List all Todos
  • Update docs
  • Syncing
  • Testing
  • More

API

  • Provider
  • usePouch
  • useDoc
  • useAllDocs
  • useFind
  • useView

Testing

Now that everything is working, let's make sure that it stays that way!

Packages to install

There are 3 packages I recommend you'll install:

  • pouchdb-adapter-memory
  • react-hooks-testing-library
  • React Testing Library (pre installed with Create-React-App)
npm
yarn
npm i -D pouchdb-adapter-memory @testing-library/react-hooks @testing-library/react
yarn add -D pouchdb-adapter-memory @testing-library/react-hooks @testing-library/react

pouchdb-adapter-memory

pouchdb-adapter-memory is a PouchDB Adapter. Adapters translate how your documents are stored and accessed. For example pouchdb-adapter-http (pre installed on most PouchDB setups) translates them into CouchDB's HTTP API.

But pouchdb-adapter-memory only stores them in memory. Perfect or testing!

react-hooks-testing-library

react-hooks-testing-library is a really good testing library, specialized in testing React Hooks.

The documentation for it can be found on https://react-hooks-testing-library.com/.

You can use it to test your own hooks. Be they extensions of hooks from usePouchDB or your own.

React Testing Library

React Testing Library comes pre-installed with create-react-app. It is a testing library that encourage you to test from the users perspective.

The documentation for it can be found at https://testing-library.com/docs/react-testing-library/intro.

Tests

Your tests should be closed systems. And no test before or after it should influence them. To achieve this I recommend that you create a new PouchDB database before each test. And that db should have the pouchdb-adapter-memory active.

// Using jest
import PouchDB from 'pouchdb'
import memory from 'pouchdb-adapter-memory'

// add the adapter to PouchDB
PouchDB.plugin(memory)

let myPouch = null

beforeEach(() => {
  // before each test, create a new DB with the memory adapter.
  // nothing will be saved on disc!
  myPouch = new PouchDB('test', { adapter: 'memory' })
})

afterEach(async () => {
  // Destroy the database after each test,
  // so that no data will be left from the previous test.
  await myPouch.destroy()
})

Also remember, that you must add all needed document before/during the test!

Components

All hooks must be in child components of <Provider />.

For React Testing Library you can warp your component with <Provider />:

import React from 'react'
import { render } from '@testing-library/react'
import PouchDB from 'pouchdb'
import memory from 'pouchdb-adapter-memory'

import TodoList from './TodoList'

PouchDB.plugin(memory)

let myPouch = null

beforeEach(() => {
  myPouch = new PouchDB('test', { adapter: 'memory' })
})

afterEach(async () => {
  await myPouch.destroy()
})

test('Test Component', async () => {
  // Add needed documents
  const putResult = await myPouch.bulkDocs([
    {
      _id: new Date(2020, 4, 30, 22, 03, 45, 0).toJSON(),
      type: 'todo',
      text: 'a todo',
      done: false,
    },
    {
      _id: new Date(2020, 4, 30, 21, 03, 45, 0).toJSON(),
      type: 'todo',
      text: 'moar todo',
      done: false,
    },
  ])

  // Render the Component
  const { queryByByText } = render(
    <Provider pouchdb={db}>
      <TodoList />
    </Provider>
  )

  const first = queryByByText('moar todo')
  expect(first).toBeTruthy()
  expect(first.nodeName).toBe('SPAN')
  expect(first.parentNode.nodeName).toBe('LI')
  expect(first.previousElementSibling.nodeName).toBe('INPUT')
  expect(first.previousElementSibling.nodeName.type).toBe('checkbox')

  const second = queryByByText('a todo')
  expect(second).toBeTruthy()
  expect(second.nodeName).toBe('SPAN')
  expect(second.parentNode.nodeName).toBe('LI')
  expect(second.previousElementSibling.nodeName).toBe('INPUT')
  expect(second.previousElementSibling.nodeName.type).toBe('checkbox')

  expect(second.parentNode.previousElementSibling).toBe(first.parentNode)
})

myPouch.bulkDocs is a method to create/update multiple docs in one go.

Hooks

To test hooks that depend on one of usePouchDB's hooks, you also must warp it in <Provider />.

react-hooks-testing-library's renderHook function can receive in the second argument a warper (documented here).

Let's test the addTodo from Add Todos extracted into a hook:

// hooks.js
import { useCallback } from 'react'
import { usePouch } from 'use-pouchdb'

// This hook returns a function, which we then call with the todo's text.
export function useAddDoc() {
  const db = usePouch()

  return useCallback(
    text => {
      const doc = {
        _id: new Date().toJSON(),
        type: 'todo',
        text: text,
        done: false,
      }

      return db.put(doc)
    },
    [db]
  )
}
import React from 'react'
import { renderHook } from '@testing-library/react-hooks'
import PouchDB from 'pouchdb'
import memory from 'pouchdb-adapter-memory'
import { Provider } from 'use-pouchdb'

import { useAddDoc } from './hooks'

PouchDB.plugin(memory)

let myPouch = null

beforeEach(() => {
  myPouch = new PouchDB('test', { adapter: 'memory' })
})

afterEach(async () => {
  await myPouch.destroy()
})

test('add document', async () => {
  const wrapper = ({ children }) => (
    <Provider pouchdb={myPouch}>{children}</Provider>
  )
  const { result } = renderHook(() => useAddDoc(), {
    wrapper,
  })

  expect(typeof result.current).toBe('function')

  await result.current('test todo')

  const { rows } = await myPouch.allDocs({ include_docs: true })
  expect(rows).toHaveLength(1)
  expect(rows[0]).toEqual({
    _id: expect.any(String),
    _rev: expect.any(String),
    type: 'todo',
    text: 'test todo',
    done: false,
  })
})

Now we are finished with our Todo example. All Todos are replicated, users can sign up and log in. I know, this was a long tutorial, but we did cover a lot!

Happy coding! ๐ŸŽ‰๐ŸŽŠ

โ† SyncingMore โ†’
  • Packages to install
    • pouchdb-adapter-memory
    • react-hooks-testing-library
    • React Testing Library
  • Tests
    • Components
    • Hooks
usePouchDB
Docs
Getting StartedAPI Reference
Contact
BlogGitHubStar
Impressum
Copyright ยฉ 2023 Christopher Astfalk