• Stars
    star
    381
  • Rank 112,502 (Top 3 %)
  • Language
    JavaScript
  • License
    The Unlicense
  • Created over 7 years ago
  • Updated 8 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Jest package for mocking mongoose models

Mockingoose CircleCI

logo

A Jest package for mocking mongoose models

Installation

With NPM:

$ npm i mockingoose -D

With Yarn:

$ yarn add mockingoose -D

Import the library

const mockingoose = require('mockingoose');

Usage

// user.js
const mongoose = require('mongoose');
const { Schema } = mongoose;

const schema = Schema({
  name: String,
  email: String,
  created: { type: Date, default: Date.now },
});

module.exports = mongoose.model('User', schema);

mockingoose(Model).toReturn(obj, operation = 'find')

Returns a plain object.

// __tests__/user.test.js
const mockingoose = require('mockingoose');

const model = require('./user');

describe('test mongoose User model', () => {
  it('should return the doc with findById', () => {
    const _doc = {
      _id: '507f191e810c19729de860ea',
      name: 'name',
      email: '[email protected]',
    };

    mockingoose(model).toReturn(_doc, 'findOne');

    return model.findById({ _id: '507f191e810c19729de860ea' }).then(doc => {
      expect(JSON.parse(JSON.stringify(doc))).toMatchObject(_doc);
    });
  });

  it('should return the doc with update', () => {
    const _doc = {
      _id: '507f191e810c19729de860ea',
      name: 'name',
      email: '[email protected]',
    };

    mockingoose(model).toReturn(_doc, 'update');

    return model
      .update({ name: 'changed' }) // this won't really change anything
      .where({ _id: '507f191e810c19729de860ea' })
      .then(doc => {
        expect(JSON.parse(JSON.stringify(doc))).toMatchObject(_doc);
      });
  });
});

mockingoose(Model).toReturn(fn, operation = 'find')

Allows passing a function in order to return the result.

You will be able to inspect the query using the parameter passed to the function. This will be either a Mongoose Query or Aggregate class, depending on your usage.

You can use snapshots to automatically test that the queries sent out are valid.

// __tests__/user.test.js
const mockingoose = require('mockingoose');
const model = require('./user');

describe('test mongoose User model', () => {
  it('should return the doc with findById', () => {
    const _doc = {
      _id: '507f191e810c19729de860ea',
      name: 'name',
      email: '[email protected]',
    };
    const finderMock = query => {
      expect(query.getQuery()).toMatchSnapshot('findById query');

      if (query.getQuery()._id === '507f191e810c19729de860ea') {
        return _doc;
      }
    };

    mockingoose(model).toReturn(finderMock, 'findOne'); // findById is findOne

    return model.findById('507f191e810c19729de860ea').then(doc => {
      expect(JSON.parse(JSON.stringify(doc))).toMatchObject(_doc);
    });
  });
});

mockingoose(Model).reset(operation = undefined)

will reset Model mock, if pass an operation, will reset only this operation mock.

it('should reset model mock', () => {
  mockingoose(model).toReturn({ name: '1' });
  mockingoose(model).toReturn({ name: '2' }, 'save');

  mockingoose(model).reset(); // will reset all operations;
  mockingoose(model).reset('find'); // will reset only find operations;
});

you can also chain mockingoose#ModelName operations:

mockingoose(model)
  .toReturn({ name: 'name' })
  .toReturn({ name: 'a name too' }, 'findOne')
  .toReturn({ name: 'another name' }, 'save')
  .reset('find');

mockingoose.resetAll()

will reset all mocks.

beforeEach(() => {
  mockingoose.resetAll();
});

Operations available:

  • find - for find query
  • findOne - for findOne query
  • count - for count query (deprecated)
  • countDocuments for count query
  • estimatedDocumentCount for count collection documents
  • distinct - for distinct query
  • findOneAndUpdate - for findOneAndUpdate query
  • findOneAndRemove - for findOneAndRemove query
  • update - for update query (DEPRECATED)
  • updateOne - for updateOne query
  • updateMany - for updateMany query
  • save - for create, and save documents Model.create() or Model.save() or doc.save()
  • remove - for remove query (DEPRECATED)
  • deleteOne - for deleteOne query
  • deleteMany - for deleteMany query
  • aggregate - for aggregate framework
  • insertMany - for Model.insertMany() bulk insert, can also pass { lean: true, rawResult: true } options.

Notes

All operations work with exec, promise and callback.

  • if you are using Model.create and you don't pass a mock with mockingoose you'll receive the mongoose created doc (with ObjectId and transformations)

  • validations are working as expected.

  • the returned document is an instance of mongoose Model.

  • deleteOne and updateOne operation returns original mocked object.

  • you can simulate Error by passing an Error to mockingoose:

    mockingoose(model).toReturn(new Error('My Error'), 'save');
    
    return model.create({ name: 'name', email: '[email protected]' }).catch(err => {
      expect(err.message).toBe('My Error');
    });
  • you can mock .populate in your mocked result just be sure to change the Schema's path to appropriate type (eg: Object | Mixed):

    User.schema.path('foreignKey', Object);
    
    const doc = {
      email: '[email protected]',
      foreignKey: {
        _id: '5ca4af76384306089c1c30ba',
        name: 'test',
        value: 'test',
      },
      name: 'Name',
      saveCount: 1,
    };
      
    mockingoose(User).toReturn(doc);
      
    const result = await User.find();
      
    expect(result).toMatchObject(doc);
  • you can mock the Model.exists() by passing the findOne operator. see Issue #69

  • no connection is made to the database (mongoose.connect is jest.fn())

  • will work with node 6.4.x. tested with mongoose 4.x and jest 20.x.

  • check tests for more, feel free to fork and contribute.

Recent Changes:

  • mockingoose.ModelName is deprecated, mockingoose(Model) is the now the recommended usage, with Model being a Mongoose model class.

    Alternatively, you may pass a string with the model name.

  • mockingoose(Model).toReturn((query) => value) can now take also take a function as a parameter.

    The function is called with either a Query or Aggregate object from Mongoose, depending on the request. This allows tests to ensure that proper queries are sent out, and helps with regression testing.

Shoutout to our amazing community

Stargazers

Stargazers repo roster for @alonronin/mockingoose

Forkers

Forkers repo roster for @alonronin/mockingoose

More Repositories

1

react-atomic-design-ddd

Build React apps fast using Storybook, DDD, and Atomic Design
JavaScript
39
star
2

angular-webpack-boilerplate

JavaScript
22
star
3

react-mobx-webpack-seed

a boiler plate for React, MobX and Webpack application with tests and coverage.
JavaScript
21
star
4

Enc

idiomatic way to encode, decode and hashing
JavaScript
20
star
5

rn2021

TypeScript
10
star
6

react-tailwind-storybook

A monorepo boilerplate for developing React apps fast using Atomic Design, Tailwind and StoryBook
JavaScript
8
star
7

react-tailwind-rsbuild-boilerplate

React + React Router + Tailwind Css with RSBuild boilerplate.
TypeScript
7
star
8

connect-auth-example

JavaScript
5
star
9

style

HOC to write react component with Style
JavaScript
4
star
10

filemanager

Node.js File Manager Based on MongoDB and Cloudinary
JavaScript
4
star
11

mp3db.ru-scraper

a scraper for mp3db.ru website
JavaScript
3
star
12

botox

SDK for creating Conversational AI
JavaScript
3
star
13

jsil-02-20

Infinite scale with Node.js and CloudRun
JavaScript
2
star
14

jsil-build-react

Javascript Israel - DIY - Build Your Own React
JavaScript
2
star
15

sc-next-13-deepdub

Server Components in Next.js 13
JavaScript
2
star
16

jsil-ydnbp

Javascript IL talk
JavaScript
2
star
17

mongoose-browser-example

Example for mongoose browser validation.
JavaScript
2
star
18

nodejs-forms

like django forms to nodejs
JavaScript
1
star
19

angular-webpack-global

JavaScript
1
star
20

ios-keyboard-resize

JavaScript
1
star
21

react-next-2023

Server Components Talk at React Next 2023
TypeScript
1
star
22

create-rtw-app

Generate a React, Tailwind and Webpack 5 App (https://github.com/alonronin/react-tailwind-webpack5-boilerplate)
JavaScript
1
star
23

dust-demos

JavaScript
1
star
24

nodejs-mongoose-example

JavaScript
1
star
25

no-state-snappy

JavaScript
1
star
26

nextjs-israel-routing-pattenrs

TypeScript
1
star
27

jsfront-13-12-2023

TypeScript
1
star
28

Global-Example

Node.JS Global scope example
JavaScript
1
star
29

node-web-server

JavaScript
1
star
30

esm-nx-example

JavaScript
1
star
31

mock-server

1
star
32

jsil-02052022

Crud close to the platform
JavaScript
1
star
33

turborepo-example-tikal

JavaScript
1
star
34

tikal-pro-camp-next-13

TypeScript
1
star
35

ko-examples

JavaScript
1
star
36

react-mobx-examples

React + MobX best practices and examples.
JavaScript
1
star
37

guesty-generate-heatmap

JavaScript
1
star
38

tikal-webpack-workshop

JavaScript
1
star
39

builder

JavaScript
1
star
40

amdocs-webpack-workshop

JavaScript
1
star
41

laravel-nginx-k8s

PHP
1
star
42

nx-react-mobx

TypeScript
1
star
43

ronin

Ronin CMS
JavaScript
1
star
44

ronin-cms

An express middlware to create a CMS with dust themes and formage as backend
JavaScript
1
star