Издевательская модель Mongoose со шуткой
Я пытаюсь издеваться над моделью mongoose со jest
, но получает Cannot create property 'constructor' on number '1'
ошибке Cannot create property 'constructor' on number '1'
. Я смог воспроизвести проблему, создав проект с двумя файлами, показанными ниже. Есть ли способ издеваться над моделью мангуста со 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 = () => {
// ...
// }
Ошибка:
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)
Обновить:
Кажется, это ошибка в шутку. https://github.com/facebook/jest/issues/3073
Ответы
Ответ 1
Хорошо, у меня была та же проблема, поэтому я создаю этот пакет, чтобы решить эту проблему: https://www.npmjs.com/package/mockingoose
вот как вы можете использовать это, скажем, это ваша модель:
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);
и это ваш тест:
it('should find', () => {
mockingoose.User.toReturn({ name: 2 });
return User
.find()
.where('name')
.in([1])
.then(result => {
expect(result).toEqual({ name: 2 });
})
});
проверьте папку с тестами для получения дополнительных примеров: https://github.com/alonronin/mockingoose/blob/master/___tests___/index.test.js
нет соединений с базой данных!
Ответ 2
Другим решением является spyOn
функций prototype
модели.
Например, это приведет к сбою MyModel.save()
:
jest.spyOn(MyModel.prototype, 'save')
.mockImplementationOnce(() => Promise.reject('fail update'))
Вы можете использовать mockImplementationOnce
чтобы не иметь необходимость в mockRestore
шпиона. Но вы также можете использовать mockImplementation
и использовать что-то вроде:
afterEach(() => {
jest.restoreAllMocks()
})
Протестировано с помощью "mongoose": "^4.11.7"
и "jest": "^23.6.0"
.
Ответ 3
Mockingoose, кажется, очень хорошее решение. Но я также смог смоделировать свою модель с Jest.mock()
функции Jest.mock()
. По крайней мере, create
метод.
// in the module under the test I am creating (saving) DeviceLocation to DB
// someBackendModule.js
...
DeviceLocation.create(location, (err) => {
...
});
...
Определение модели DeviceLocation:
// DeviceLocation.js
import mongoose from 'mongoose';
const { Schema } = mongoose;
const modelName = 'deviceLocation';
const DeviceLocation = new Schema({
...
});
export default mongoose.model(modelName, DeviceLocation, modelName);
Макет DeviceLocation в папке __mocks__
в той же папке, что и модель DeviceLocation
:
// __mock__/DeviceLocation.js
export default {
create: (x) => {
return x;
},
};
в тестовом файле:
// test.js
// calling the mock
...
jest.mock('../../src/models/mongoose/DeviceLocation');
import someBackendModule from 'someBackendModule';
...
// perform the test