web-dev-qa-db-fra.com

Modèle de mangouste moqueur avec plaisanterie

J'essaie de me moquer d'un modèle mangouste avec jest, mais j'obtiens Cannot create property 'constructor' on number '1' Erreur. J'ai pu reproduire le problème en créant le projet avec 2 fichiers illustrés ci-dessous. Existe-t-il un moyen de se moquer d'un modèle mangouste avec jest?

./model.js

const mongoose = require('mongoose')
const Schema = mongoose.Schema

const schema = new Schema({
  name: String
})

module.exports = mongoose.model('Test', schema)

./model.test.js

jest.mock('./model')
const Test = require('./model')

// Test.findOne.mockImplementation = () => {
//   ...
// }

Erreur:

 FAIL  ./model.test.js
  ● Test suite failed to run

    TypeError: Cannot create property 'constructor' on number '1'

      at ModuleMockerClass._generateMock (../../jitta/sandbox/rest_api/node_modules/jest-mock/build/index.js:458:34)
      at Array.forEach (native)
      at Array.forEach (native)
      at Array.forEach (native)

Mise à jour:

Semble être un bug en plaisantant. https://github.com/facebook/jest/issues/307

13
harinsa

ok, j'ai eu le même problème donc j'écris ce paquet pour résoudre ce problème: https://www.npmjs.com/package/mockingoose

voici comment vous pouvez l'utiliser disons que c'est votre modèle:

import mongoose from 'mongoose';
const { Schema } = mongoose;

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

export default mongoose.model('User', schema);

et voici votre test:

it('should find', () => {
  mockingoose.User.toReturn({ name: 2 });

  return User
  .find()
  .where('name')
  .in([1])
  .then(result => {
    expect(result).toEqual({ name: 2 });
  })
});

consultez le dossier des tests pour plus d'exemples: https://github.com/alonronin/mockingoose/blob/master/___tests___/index.test.js

aucune connexion n'est établie avec la base de données!

8
Alon Valadji

Une autre solution consiste à spyOn le modèle prototype fonctions.

Par exemple, cela fera échouer MyModel.save():

    jest.spyOn(MyModel.prototype, 'save')
      .mockImplementationOnce(() => Promise.reject('fail update'))

Vous pouvez utiliser mockImplementationOnce pour ne pas avoir à mockRestore l'espion. Mais vous pouvez également utiliser mockImplementation et utiliser quelque chose comme:

afterEach(() => {
  jest.restoreAllMocks()
})

Testé avec "mongoose": "^4.11.7" et "jest": "^23.6.0".

8
Stephane L

La mockingoose semble être une très bonne solution. Mais j'ai également pu me moquer de mon modèle avec la fonction Jest.mock(). Au moins create méthode.

// in the module under the test I am creating (saving) DeviceLocation to DB
// someBackendModule.js
...
DeviceLocation.create(location, (err) => {
...
});
...

Définition du modèle DeviceLocation:

// DeviceLocation.js
import mongoose from 'mongoose';

const { Schema } = mongoose;
const modelName = 'deviceLocation';

const DeviceLocation = new Schema({
...
});

export default mongoose.model(modelName, DeviceLocation, modelName);

Maquette DeviceLocation dans le __mocks__ dossier dans le même dossier que DeviceLocation modèle:

// __mock__/DeviceLocation.js
export default {
    create: (x) => {    
        return x;
    },
};

dans le fichier de test:

// test.js
// calling the mock
...
jest.mock('../../src/models/mongoose/DeviceLocation');
import someBackendModule from 'someBackendModule';
...
// perform the test
0
Jirik