Error: A method named '/x/insert' is already defined

Hi,

I am trying to test a package that I am working on - writing some server side integration tests. I am using Jasmine and Velocity. A problem I am having is that I am getting the following error in one of my tests:

Error: A method named '/contentTypes/insert' is already defined

I have two integration tests set up so far and in testing my functions, I am declaring a new collection more than once, because I am declaring it once inside each test.

How can I set it up so that when my test has completed, the collection no longer exists so that when I attempt to create it again then it would be as if it had never existed.

I tried the following in cleaning up at the end of a test, but it doesn’t work

Collections.contentTypes = null; // doesn't work
delete Collections.contentTyoes; // doesn't work

Any ideas?

Thanks

I can think of two approaches:

  • define the collection once, then just clear it after each test instead of trying to make new JS objects. After all, you’re not testing Meteor’s collection API; you just want a clean database
  • define a collection with a random ID instead of a fixed ID; then you can declare as many as you want. I think some of the Meteor tests do this.

Check out https://github.com/HarvardEconCS/turkserver-meteor/blob/master/tests/utils.coffee#L26 for a easy way to wrap test functions to do cleanup.

As alternative you can use a local collection and pass it to the object under test.

var myLocalCollection = new Mongo.Collection(null);

The clear approach is also quiet simple:

beforeAll(function () {
  this.collection = new Mongo.Collection('myCollection');
});

afterEach(function () {
  this.collection.remove({});
});
3 Likes

Thanks for the replies everyone. I think I will go with setting up the collection in the initial test and not declaring it each time again.

It would be better to have things set up so that the application state is completely reset after each test is run, I think this is something that can be done for now.

1 Like

How would you handle this on the client side? You get an error with something like Cannot remove untrusted code

So, I hacked together a solution. Though, I’m not sure about the ramifications. I don’t think it’s a big deal if you’re only using it in tests:

describe('Test with collection', function() {
	beforeEach(function() {
		if (Meteor.isServer) {
			delete Meteor.server.method_handlers['/foo/insert'];
			delete Meteor.server.method_handlers['/foo/update'];
			delete Meteor.server.method_handlers['/foo/remove'];
		}
		else {
			delete Meteor.connection._stores.foo;
			delete Meteor.connection._methodHandlers['/foo/insert'];
			delete Meteor.connection._methodHandlers['/foo/update'];
			delete Meteor.connection._methodHandlers['/foo/remove'];
		}
	});
        it('create collection called foo', function() {
                var collection = new Mongo.Collection('foo');
                // do some assertions
        });
        it('some other test with collection called foo', function() {
                var collection = new Mongo.Collection('foo');
                // do some assertions
        });
});

FWIW, just created package here: https://atmospherejs.com/awei01/mongo-test-utils