Unit Testing With Meteor 1.3

Written by Pete Corey on Dec 21, 2015.

It’s no secret that I love testing. My ideal testing setup is a neatly mocked, blazingly fast unit test suite backed by a sprinkling of happy-path end-to-end tests as a last bastion against bugs. I want my test pyramid!

Until very recently, this setup has been at odds with how Meteor has envisioned software testing. Meteor has always placed more emphasis on end-to-end testing, effectively turning the test pyramid into a deliciously unstable ice cream cone.

The Problem With End-to-end

Velocity is hesitantly the official solution for Meteor testing. Velocity is fundamentally designed to run end-to-end tests on a second, mirrored, instance of your application. While writing unit tests to run under Velocity is possible and encouraged, it can take anywhere from fifteen to thirty seconds to see the results of your testing, due to server restart delays.

Fifteen seconds is a huge amount of time to wait for unit test! In fifteen seconds, I can easily lose context on the code under test, or even worse, I might start browsing Twitter.

What About Mocha

If I want faster unit tests, why not use a more standard test runner like vanilla Mocha, or Jasmine? Until very recently, this was nearly impossible due to the fact that Meteor’s application architecture had no real notion of “modules”. It was a challenge to write a Mocha test and only pull in the target module under test. To give the module context, you’d have to load up the rest of the Meteor application in its entirety.

Meteor packages were an attempt to solve this problem, and they were a solid step in the right direction. They allowed us to isolate a small chunk of our application and write targeted tests for that chunk. Unfortunately, within each package, it was very difficult to further isolate individual components; the entire package had to be treated as a single “unit”, which could be unfeasible for larger packages.

ES6 Modules to the Rescue

Thankfully, MDG (specifically Ben Newman) has come to our rescue! Meteor 1.3 is introducing full support for ES6 modules within Meteor applications and packages. This paves the way for fast unit testing within the Meteor ecosystem. Being able to structure our projects into small, isolated units means that we’re also able to test those isolated units under a microscope.

As of writing this post, Meteor 1.3 is available as an early beta release. Follow these instructions to try out the release, and take a look at the modules readme for a great overview on how to use ES6 modules in your project.

Leveraging this new functionality takes a bit of work, but the payoffs are well worth the effort. Let’s dive into how we would use ES6 modules to set up a unit testing framework in our application.

Setting Up The Suite

First thing’s first, let’s get our application set up to run unit tests. We’re going to be using Mocha spiced up with Chai and Sinon. We’ll also want to write our unit tests in ES6, so we’ll include Babel as well. Let’s set up npm for our project and pull in the development dependencies we’ll need to get testing:

npm init
npm i --save-dev mocha chai sinon sinon-chai \
                 babel-register babel-preset-es2015

Now we’ll need to set up our test directory. Normally, mocha tests are placed in a test/ directory, but Meteor will interpret that was a source directory and compile everything within it. Instead, we’ll keep our tests in tests/, which Meteor happily ignores.

mkdir tests/
touch tests/foo.js

Now we have a test file called foo.js in our tests folder. Finally, let’s add an npm test script that uses the Babel compiler, just to make our lives easier. Add the following entry to the "scripts" entry of your package.json:

"test": "mocha ./tests --compilers js:babel-register"

So now we’ve told mocha to use Babel to compile our ES6 before it runs our tests, but we need to tell it which set of ES6 features we want to support.

Add a new file called .babelrc to your project. In that file, we’ll specify that we want to use the "es2015" Babel preset:

  "presets": ["es2015"]

That’s it! Now we can run our test suite:

npm test

Or we can run it in watch mode, which will instantly rerun the suite every time any Javascript files in or below the current working directory change:

npm test -- -w

You should see a message like this, indicating that our test suite is working:

0 passing (0ms)

Now it’s time to add our tests!

Breaking Down The Tests

Let’s say we have a module in our application called Foo. Foo is simple. Foo has a method called bar that always returns "woo!". How would we write a test for that?

First, we’ll need to pull in our Foo module. This is done through a simple ES6 import:

import {Foo} from "../foo";

Next, we’ll write a test that verifies the behavior we described above:

describe("Foo", () => {

  it("returns woo", function() {
    let foo = new Foo(Meteor);
    let bar = foo.bar();


That’s fairly straight-forward. We’re creating an instance of Foo, and we’re running bar(). Lastly, we assert that the value we got from bar() is "woo!".

Foo has another method called doSomething. doSomething makes a call to a Meteor method called "something" and passes it the value of bar().

Testing for this behavior is a little more complicated. We’re going to write a test double for the Meteor.call method that will let us spy on how this method is used by our code under test. Check it out:

let Meteor;
beforeEach(function() {
  Meteor = {
    call: sinon.spy()


it("does something", function() {
  let foo = new Foo(Meteor);
  expect(Meteor.call).to.have.been.calledWith("something", "woo!");

Once again, we create an instance of Foo. However this time, we call doSomething() on the instance of Foo, and then we assert that the Meteor.call method was called with the arguments "something" and "woo!". We can make this kind of assertion because we’ve replaced the normal Meteor.call with a spy, which lets us observe all kinds of interesting things about how a function is used and how it behaves during the test.

Inject Your Dependencies

You’ll notice that each of these tests are passing a Meteor object into Foo. If you dig into the Foo module, you’ll see that any interactions it has with the outside world of Meteor are done through this passed in object:

export class Foo {
  constructor(Meteor) {
    this.Meteor = Meteor;
  bar() {
    return "woo!";
  doSomething() {
    this.Meteor.call("something", this.bar());

In this scenario, Meteor is a dependency of Foo. Foo needs Meteor to function. This technique of passing in dependencies is known as Dependency Injection, and can be very useful.

Accessing Meteor through a reference provided at construction may seem strange at first; the Meteor object is usually isomorphically global. It’s everywhere! But as we’ve seen, by being able to control what our module thinks is the Meteor object, we can underhandedly trick it into calling our mocked methods, which lets us test our units of code faster and more consistently.

At this point, if you’ve built our your Foo and its corresponding tests, your watching test runner should be showing you two passing tests (completed in milliseconds):

   ✓ returns woo
   ✓ does something

2 passing (2ms)

You can see the full test file, with a little extra boilderplate, on Github, along with the source for the Foo module.

Final Thoughts

I couldn’t be more happy about module support coming to Meteor in 1.3. While restructuring our applications into modules may take some upfront work, I truly believe that the benefits of this kind of structure will far outweigh the initial costs.

Let’s build our test pyramids!

Meteor Club Q&A on Security

Written by Pete Corey on Dec 14, 2015.

A few weeks ago, I had the chance to do a Meteor Club Q&A with Josh Owens. We spent an hour or so talking about various topics revolving around Meteor and Meteor security and answering questions submitted by the community. The whole process was a lot of fun. You should check out the whole Q&A on Youtube, or take a look below:

During the Q&A, we covered a variety of topics ranging from data-in-motion/data-at-rest security, to the positives and negatives of collection validators, all the way through to best practices for securing multi-tenant Meteor applications.

Do you have any questions about Meteor security that we didn’t discuss in the Q&A? If so, shoot me a tweet, or send me an email!

Scanning Meteor Projects for Node Vulnerabilities

Written by Pete Corey on Dec 7, 2015.

Meteor does not exist in a bubble. All of Meteor is built on top of Node.js. This means that while security projects like east5th:package-scan can help us find Meteor specific security problems in our projects, we may still be vulnerable to an entire world of vulnerabilities that exist within the Node ecosystem.

There are many Node tools that, like east5th:package-scan, will dig through the Node packages being used by your project and alert you if it finds any packages with known security vulnerabilities.

Two great tools that do this are the Node Security Project and Snyk. While these tools are designed to be used with a vanilla Node project, with a little convincing it’s possible to use them in the context of a Meteor project.

Anatomy of a Bundle

It can be difficult to determine which Node packages are being used by a Meteor application. Each Meteor package can pull in its own set of Npm packages, and these dependencies can be difficult to see unless the Meteor package has been explicitly cloned into the PACKAGE_DIRS directory.

Thankfully, a bundled Meteor application pulls all of these dependencies into a single location. Once an application is bundled, we can dig into the server Node project (found in .build/bundle/programs/server). From there we can browse through all of the Node dependencies being used by our various Meteor packages: npm/*/node_modules/*.

A brand new Meteor project (meteor create foo) immediately pulls in over a dozen Node packages. Check them out:

├── babel-compiler         <- Meteor package
│   └── node_modules
│       └── meteor-babel   <- Node package
├── ddp-client
│   └── node_modules
│       ├── faye-websocket
│       └── permessage-deflate
├── ddp-server
│   └── node_modules
│       ├── permessage-deflate
│       └── sockjs
├── ecmascript-runtime
│   └── node_modules
│       └── meteor-ecmascript-runtime
├── es5-shim
│   └── node_modules
│       └── es5-shim
├── logging
│   └── node_modules
│       └── cli-color
├── meteor
│   └── node_modules
│       └── meteor-deque
├── mongo
│   └── node_modules
│       └── mongodb-uri
├── npm-mongo
│   └── node_modules
│       └── mongodb
├── promise
│   └── node_modules
│       └── meteor-promise
└── webapp
    └── node_modules
        ├── connect
        ├── send
        └── useragent

Using Node Security Project

We can navigate into any of these Node package directories and run an NSP scan. For example, we can check the sockjs package use by ddp-server like this:

cd .build/bundle/programs/server/npm/ddp-server/node_modules/sockjs
nsp check

Thankfully, there are no known vulnerabilities in this Node package:

(+) No known vulnerabilities found

We could manually run this check for each Node package, but that would be incredibly time consuming. Why not automate the process?

I wrote a quick bash script that looks for each package.json found within these top-level Node project folders and runs NSP on them. Here’s the script:

#!/usr/bin/env bash

find bundle/programs/server/npm/*/node_modules/*/package.json |
while read file; do
  DIR="$(dirname $file)"
  pushd "${DIR}" > /dev/null
  OUTPUT="$(nsp check --output summary --color)"
  if [ $? != 0 ]; then
    echo -e "${OUTPUT}"
  popd > /dev/null

I named this script mscan and threw it into my ~/bin folder. To use it, build your meteor project, navigate into the newly created build directory, and run the script:

meteor build --directory .build &&
cd .build &&

Even for a brand new Meteor project, the results of this scan are somewhat suprising:

(+) 3 vulnerabilities found
 Name        Installed   Patched     Path   More Info
 uglify-js   2.2.5       >=2.6.0            https://nodesecurity.io/advisories/48
 uglify-js   2.2.5       >= 2.4.24          https://nodesecurity.io/advisories/39
 uglify-js   2.4.24      >=2.6.0            https://nodesecurity.io/advisories/48

(+) 4 vulnerabilities found
 Name   Installed   Patched    Path             More Info
 send   0.1.4       >=0.11.1   connect > send   https://nodesecurity.io/advisories/56
 send   0.1.4       >= 0.8.4   connect > send   https://nodesecurity.io/advisories/32
 qs     0.6.5       >= 1.x     connect > qs     https://nodesecurity.io/advisories/28
 qs     0.6.5       >= 1.x     connect > qs     https://nodesecurity.io/advisories/29

It looks like Meteor core is pulling in a few Node packages with known security issues. Very interesting! It’s worth taking a look at these advisories and considering what impact (if any) they might have on your Meteor application.

Drawbacks and Final Thoughts

One thing to note about the NSP tool is that it will only scan the dependencies found in a package.json file for vulnerabilities. It will not check if the package itself has any known issues. This means that if we run nsp check on the mongodb Node package, it will only report any vulnerabilities in mongodb’s dependencies, not any vulnerabilities with the package itself.

This is a known issue and the Node Security Project team are actively working on a fix.

The bash script I created to do these scans certainly isn’t the most user friendly tool. If you find it interesting or useful, I can give it a little more love and turn it into a Npm-installable command line tool, which may be more straight-forward to use.