samedi 24 décembre 2016

How to unit test a meteor method with practicalmeteor:mocha

I'm having a nightmare writing unit tests for meteor. There are too many old, outdated articles and too few clear, relevant pieces of documentation for me to be able to work out what I actually need to do to get this to work.

I'm running in to problem after problem and just really hope someone can show me how they would write a test for one of my methods so I can see what they have done and reverse engineer it for the rest of my methods.

Here's a method I'd like to write a test for:

Meteor.methods({
  'client.new':( clientDetails ) => {
    check( clientDetails, {
      name: String,
      numberTeamMembers: String
    });

    clientDetails.teamMembers = [];

    if(!Meteor.userId() || !Roles.userIsInRole(Meteor.userId(), 'administrator')) {
      throw new Meteor.Error('500', 'You are not authorised to do this.');
    }

    if(Clients.findOne({ name: clientDetails.name})) {
      throw new Meteor.Error('500', 'This client name already exists!');
    };

    return Clients.insert(clientDetails);
  },
});

So far I've got the below:

import { Meteor } from 'meteor/meteor';
import { expect, be } from 'meteor/practicalmeteor:chai';
import { describe, it, before } from 'meteor/practicalmeteor:mocha';
import { resetDatabase } from 'meteor/xolvio:cleaner';
import { Random } from 'meteor/random';

import { Clients } from '/imports/api/clients/clients.js';

import '/imports/api/clients/server/methods.js';

describe('Client Methods in API', function() {
  before(function() {
    resetDatabase();
  });

  it('can create a Client', function(){
    let clientName = "Microsoft",
        numberTeamMembers = "5",
        data = {
          name: clientName,
          numberTeamMembers: numberTeamMembers
        };

    let userId = Accounts.createUser({username: "admin", email: "admin@admin.com", password: "password"});
    Meteor.users.update({ _id: userId }, { $set: { roles: [ 'administrator' ] }});

    let method = Meteor.server.method_handlers['client.new'];

    method.apply(userId, [data]);


    let client = Clients.findOne();

    expect(Clients.find().count()).to.equal(1);
    expect(client.name).to.equal(clientName);
    expect(client.numberTeamMembers).to.equal(numberTeamMembers);
  });
});

The errors the above test throws are firstly it tells me that Meteor.userId can only be invoked in method calls. Use this.userId in publish functions. which is irrelevant because this is a method I'm testing. Secondly, the method throws the error ('You are not authorised to do this') so either it doesn't recognise the Meteor.userId() or the fact that the user is in the 'administrator' role.

If someone could show me how they would test that method I'd really appreciate it!

Thanks

Aucun commentaire:

Enregistrer un commentaire