hwillson / meteor-stub-collections

Stub out Meteor collections with in-memory local collections.
MIT License
24 stars 17 forks source link

There is already a collection named "<collection name>" #6

Closed RafaelVidaurre closed 7 years ago

RafaelVidaurre commented 7 years ago

I'm trying to stub a collection that comes from a package, it is defined like this:

import url from 'url';
import { Mongo } from 'meteor/mongo';
import { Account as AccountSchema } from 'meteor/myapp-schema';
import Account from '../models/account';
const { adminHost } = Meteor.settings.public;

class Accounts extends Mongo.Collection {
  constructor() {
    const accounts = super('accounts', {
      transform(doc) {
        return new Account(doc);
      },
    });

    accounts.attachSchema(AccountSchema, { transform: true });
    return accounts;
  }
}

export default new Accounts;

Account model has:

const { adminHost } = Meteor.settings.public;

export default class Account {
  constructor(doc) {
    Object.assign(this, doc);
  }

  adminHost() {
    return `${this.slug}.${adminHost}`;
  }
}

On the Client I'm trying to stub like this:

import StubCollections from 'meteor/hwillson:stub-collections';
import { Accounts } from 'meteor/app-collections';

describe('WidgetFormEdit', () => {
  if (Meteor.isClient) {
    StubCollections.stub([Accounts]);
    Accounts.insert({ foo: 'bar' });
  }
});

I'm getting Uncaught Error: There is already a collection named "accounts"

hwillson commented 7 years ago

You're overriding the default Mongo.Collection constructor but not accepting the same constructor parameters. Internally StubCollections makes a call like this on your Accounts collection:

const pair = {
  localCollection: new collection.constructor(null, options),
  collection,
};

It's trying to pass null into your constructor, which would create the needed local collection, but your constructor is ignoring the passing in null parameter (and trying to instantiate another accounts collection). I would recommend changing your constructor around to something like:

constructor(name, options) {  
  const collectionName = name || 'accounts';
  const accounts = super(collectionName, {
    transform(doc) {
      return new Account(doc);
    },
  });
  ...
RafaelVidaurre commented 7 years ago

Thanks a bunch I'll try that!