Rockettomatoo
Rockettomatoo

Reputation: 277

Meteor mocha test subscriptions

I'm currently working on writing client-side tests for my application using practicalmeteor:mocha. Therefor I need to insert a record into a mongo collection before every step.

Following the concepts of meteor, I wrote some meteor methods to insert/update/delete the records. If I want to test the expected behaviour, I assume I have to call the appropiate method (to insert a record for example) and then have to wait for the subscription to synchronize the record to the client so I can verify the insert.

I tried a few things but none of them seems to work:

describe('a topic', function() {
    beforeEach(async function(done) {
        let res = await new Promise((resolve, reject) => {
            Meteor.call('topics.createNew', function(err, res) {
                if(err) return reject(err);
                resolve(res); //res is the _id from the generated record
            });
        });

        //subscribe to single record (the one just created)
        let subscription = Meteor.subscribe('topics.details', res); 

        //i assume this runs every time the publish function calls ready and therefor is also run when the new record is published
        Tracker.autorun((computation) => {
            let count = TopicsCollection.find({}).count();
            //console.log('topic count: ' + count);                

            if(subscription.ready() && count === 1) {
                computation.stop();
                done();
            }
        });
    });
});

I logged the counted documents and had luck when i wrapped the autorun-Funktion into a Promise but in neither of both cases, done() was called causing a timeout in mocha.

I already had a look on this question but I think it doesnt really help in my situation since I wait for every possible callback and I'm working with a plain Collection and the guy in the question above uses an accounts-package.

Can anyone suggest a better/working solution for this problem?
Thanks in advance! :D

Upvotes: 0

Views: 439

Answers (1)

Jankapunkt
Jankapunkt

Reputation: 8413

Summarizing your current setup:

  • calling a method on the client
  • insert some doc on the server
  • subscribe to the pub from the client
  • verify inserts by the subscribed data

Which is a big blackbox that is on the scope here. Additionally you are testing things, that are already tested by the Meteor core team: integration tests of Methods and Publications between server and client.

To prevent waste of time, you can split up your setup into two tests:

  • Test the Meteor method as a unit
  • Test the Meteor publication as a unit

If those tests are defining the intended behavior with correct permission levels, you can assume, that if you are a logged in user with the correct permission level subscribing to your publication, that this user will get the resulting behavior as you have tested in the units. As I pointed out before, the pub/sub system should be assumed as 'working' by definition.

1. Test the method, server side only

Use hwillson:stub-collections to get a 'mock' of your collection, use practicalmeteor:sinon to mock your Meteor.user() object to test different permission levels.

2. Test the publication, server side only

Use johanbrook:publication-collector to test if your publication is running correctly and dburles:factory create mocks of your collection's data.

No need then for a complex test setup on the client side.

Upvotes: 2

Related Questions