I’m looking to add unit tests and mocking to my existing code base on Meteor 1.8 uing Jest and maybe even React Testing Framework.
I don’t see many complete examples of mocking things like a Mongo (‘meteor/mongo’) collection or a Meteor method (‘meteor/meteor’) for example.
My setup:
package.json
"devDependencies": {
"faker": "^4.1.0",
"jest": "^24.7.1",
"meteor-jest-stubs": "^1.8.0"
}
jest.config.js
module.exports = {
transform: {
'^.+\\.jsx?$': 'babel-jest',
},
moduleFileExtensions: [
'js',
'jsx',
],
modulePaths: [
'<rootDir>/node_modules/',
'<rootDir>/node_modules/meteor-jest-stubs/lib/',
],
unmockedModulePathPatterns: [
'/^imports\\/.*\\.jsx?$/',
'/^node_modules/',
],
modulePathIgnorePatterns: [
".meteor"
]
};
If I run jest --watch
the following code fails
mongo.test.js
const Mongo = require('meteor/mongo')
const accounts = new Mongo.Collection("accounts");
function getDependentCounts() {
}
it('first mongo test', () => {
const dependentCounts = getDependentCounts(); /*?*/
expect(dependentCounts).toBe(0)
});
Error:
TypeError: Mongo.Collection is not a constructor
1 |
2 | const Mongo = require('meteor/mongo')
> 3 | const accounts = new Mongo.Collection("accounts");
| ^
4 |
5 | function getDependentCounts() {
I understand that I need to mock this Mongo call, and I have not done so yet. But doesn’t Jest even have the capability to pull in ‘meteor/mongo’ and actually make a call to MongoDB? How are we suppose to do integration testing at some point?
And when I add a Collection mock:
Add a mock directory and a mapper to resolve
moduleNameMapper: {
"^meteor/(.*)": "<rootDir>/.mocks/$1.js"
},
Mock the collection
const Collection = jest.fn();
Collection.prototype.attachSchema = jest.fn();
Collection.prototype.insert = jest.fn();
Collection.prototype.update = jest.fn();
Collection.prototype.remove = jest.fn();
Collection.prototype.findOne = jest.fn();
Collection.prototype.find = jest.fn(() => ({
count: jest.fn(),
fetch: jest.fn(),
}));
Collection.prototype.helpers = jest.fn();
Collection.prototype.before = {
insert: jest.fn(),
update: jest.fn(),
};
Collection.prototype.after = {
insert: jest.fn(),
update: jest.fn(),
};
const Mongo = { Collection };
const RemoteCollectionDriver = jest.fn();
RemoteCollectionDriver.prototype.open = jest.fn().mockReturnThis();
RemoteCollectionDriver.prototype.insert = jest.fn();
RemoteCollectionDriver.prototype.update = jest.fn();
RemoteCollectionDriver.prototype.remove = jest.fn();
RemoteCollectionDriver.prototype.findOne = jest.fn();
RemoteCollectionDriver.prototype.find = jest.fn(() => ({
count: jest.fn(),
fetch: jest.fn(),
}));
const MongoInternals = { RemoteCollectionDriver };
module.exports = {
Mongo,
MongoInternals,
};
I get this error:
Configuration error:
Could not locate module meteor/accounts-base mapped as:
/Users/aadams/Meteors/development/fp-client/.mocks/accounts-base.js.
Please check your configuration for these entries:
{
"moduleNameMapper": {
"/^meteor\/(.*)/": "/Users/aadams/Meteors/development/fp-client/.mocks/$1.js"
},
"resolver": null
}
at createNoMappedModuleFoundError (node_modules/jest-resolve/build/index.js:471:17)
at Array.reduce (<anonymous>)
at SearchSource.findRelatedTests (node_modules/@jest/core/build/SearchSource.js:280:30)
at SearchSource.findTestRelatedToChangedFiles (node_modules/@jest/core/build/SearchSource.js:363:14)