Samo
Samo

Reputation: 8240

Testing practices for Meteor

This isn't so much a question of technology; I see that a lot of people are using Mocha, which looks neat, so I'll try it.

What I'm wondering is how people deal with testing things like models that are tied to Meteor collections. Would you use sinon to mock the database records? Are there framework files that you would load using require so that you could use Meteor.Collection?

Edit

To be more specific, I'm writing an app that uses several Minimongoid models. If you've seen one of these, you know that every model's @_collection property is a new Meteor.Collection(...).

One of the main advantages to having a model instead of a database record is that you can attach behavior to it, and that behavior is what I'm trying to test.

So let's say you have a game involving two pieces on a board. When the player clicks a piece, we want to show all legal moves on the board by highlighting the squares. The piece has a method that determines whether or not a given location constitutes a legal move, based on how that piece moves and whether there are other pieces in its way; determining whether there are pieces in the way probably requires a database query:

class Piece extends Minimongoid
  @_collection: new Meteor.Collection('pieces')

  @find: (selector = {}, options = {}) ->
    document = @_collection.findOne(selector, options)
    if document
      model = new @(document)
      _.extend(model, model.attributes)

  @where: (selector = {}, options = {}) ->
    @_collection.find(selector, options).map (record) =>
      model = new @(record)
      _.extend(model, model.attributes)

class Bishop extends Piece
  @code: "bishop"

  isLegalMove: (location) ->
    @isOnMyPath(location) && @noPiecesInMyWay(location)

  noPiecesInMyWay: (location) ->
    _.all Piece.where({ color: @otherColor() }), (piece) -> 
      !piece.isOnMyPath(location) || (piece.location == location && piece.color == @otherColor())

So if I load this class with a testing framework, I really only see two options for testing this code:

  1. Mock the @_collection object with something like sinon
  2. Have Meteor (or parts of it) loaded by the test framework so that my models have access to Meteor.Collection

Update

About a year later I came back to this and tried out some of the suggested approaches to testing.

I took a look at RTD, which seemed to be the most complete of all the solutions available, but I could not get it to run.

I also had a look at Laika, but really did not care for the syntax. I want a BDD style syntax, and what Laika offers is rather cryptic looking in comparison.

After a bit of trial and error, however, I was able to get meteor-mocha-web to work, and so far I'm very pleased with it. It runs your app and pulls in your test files, so there's no need to mock any part of the framework. It's far from perfect of course, but it's the first thing I was able to get running and it has the syntax I prefer, so it wins. Thanks to jagill for the answer!

Upvotes: 9

Views: 1142

Answers (1)

jagill
jagill

Reputation: 692

We've run into similar problems when trying to test our app, MadEye.io. There are a lot of moving parts and edge cases, so an automated suites were essential. We've built a package meteor-mocha-web to enable testing in the Meteor context, including Session, Meteor.Collections, Deps, etc. We also gave a Lightning Talk at Meteor's Devshop 0 explaining it briefly.

It's early stages, but it's been invaluable to us, and it's covering more use-cases as people need them.

Upvotes: 3

Related Questions