Generating Test Data with Meteor Factory and Fake
The following tests set up with meteor-factory.
First create Meteor app, install packages, define collections and start server:
meteor create testApp
cd testApp
meteor add dburles:factory
meteor add babrahams:constellation
cat << EOF > collections.js
Authors = new Meteor.Collection('authors');
Books = new Meteor.Collection('books');
EOF
# Authors and Books must be defined in both servers and client
# or `Factory.create("books");` will fail.
# So they can't be defined in browser console
MONGO_URL="mongodb://localhost:27017/test" meteor
Then open http://localhost:3000/ in browser, Open constellation console with Ctrl-C. Open browser console (with F12), run codes below:
Factory.define('author', Authors, {
name: 'John Smith'
});
// all authors created through Factory have the same "name"
Factory.define('book', Books, {
authorId: Factory.get('author'),
name: 'A book',
year: function() { return _.random(1900, 2014); }
});
Now each time you run Factory.create('author');
,
a new document is inserted into the collection "authors".
You can see it on the constellation console under "authors" section.
If you want create user with different names,
add a new package meteor-fake
with meteor add anti:fake
, and modify above definitions as follows:
Factory.define('author', Authors, {
name: function() { return Fake.user({fields: ['name']}).name; }
});
Factory.define('book', Books, {
authorId: Factory.get('author'),
name: function() { return Fake.sentence(4); },
year: function() { return _.random(1900, 2014); }
});
When enable the "Autopublish" tab, you can see all the collections even after the autopublish package removed from Meteor app.
Used in Package
The container app is named "mininf", which has a package named "nfcore".
There will be 3 roles of user in this scenario, Add, Sub and Multi. Users with Add role can only ask addition questions, with Sub can only ask substraction questions, with Multi can only ask multiplication questions.
A user without a role can't ask any questions.
The users and their roles will be created with alanning/meteor-roles.
There are 2 collections, accounts and questions, whose schemas are defined with simple-schema.
Target:
Run the container app, use constellation to watch it's data; Define data schema with simple-schema; Use factory to insert user and question to collections; Run test on container app, see the result.
The implementation steps:
-
Create mininf and nfcore;
-
Add simple-schema and roles in the package definition of mininf;
-
Add jasmine and velocity in the package test definition of mininf;
-
Create schemas of users and questions in package;
-
Create collections in package and attach schemas on them;
-
Create tests;
meteor create mininf cd mininf meteor create --package leo:nfcore cat << EOF > packages/nfcore/package.js Package.describe({ name: 'leo:nfcore', version: '0.0.1', summary: '', git: '', documentation: 'README.md' }); Package.onUse(function(api) { api.versionsFrom('1.2.0.2'); api.use('ecmascript'); // this makes nfcore itself can use variable "SimpleSchema" in the source code api.use("aldeed:simple-schema@1.3.3"); api.use("alanning:roles"); // this makes any packages using nfcore can use "SimpleSchema" api.imply("aldeed:simple-schema"); api.imply("alanning:roles"); api.addFiles('nfcore.js'); api.export("NFCore"); }); Package.onTest(function(api) { api.use('ecmascript'); api.use('sanjo:jasmine@0.19.0'); api.use('anti:fake'); api.use('underscore'); api.use("dburles:factory@0.3.10"); api.use('velocity:html-reporter@0.9.0'); api.use('velocity:console-reporter@0.1.3'); api.use('leo:nfcore'); api.addFiles('nfcore-tests.js'); }); EOF
mkdir -p {common/{schemas,collections},tests,client,server} cat << EOF > common/globals.js NFCore = {}; NFCore.Schemas = {}; NFCore.Collections = {}; EOF
cat << EOF > common/schemas/accounts.js NFCore.Schemas.Accounts = new SimpleSchema({ name: { type: String } }); EOF
cat << EOF > common/schemas/accounts.js NFCore.Schemas.Questions = new SimpleSchema({ owner: { type: Meteor.Collection.ObjectID }, content: { type: String } }); EOF
cat << EOF > common/collections/collections.js NFCore.Collections.Accounts = new Mongo.Collection("accounts"); NFCore.Collections.Accounts.attachSchema(NFCore.Schemas.Accounts);
NFCore.Collections.Questions = new Mongo.Collection("questions"); NFCore.Collections.Questions.attachSchema(NFCore.Schemas.Questions); EOF
Errors, Questions and Solutions
E: meteor object [object object] has no method 'attach schema'.
S: Add api.use("aldeed:collection2@2.5.0");
and api.imply("aldeed:collection2@2.5.0");
into Package.onUse() of package.js.
E: insert failed: Access denied. No allow validators set on restricted collection for method 'insert'.
S: Add "server" as the 2nd parameter in package.js -> Package.onTest -> api.addFiles(api.addFiles('tests/accounts.js', 'server');
.
Q: In package I use Factory.create() to insert a doc into a collection, but I can't find the collection.
S: Add environment "MONGO_URL" into the test command:
VELOCITY_TEST_PACKAGES=1 MONGO_URL="mongodb://localhost:27017/test" meteor test-packages --driver-package velocity:html-reporter leo:nfcore
.