1

I'm using mocha and chai (with chai-as-promised) and I'm trying to test a mongoDB database using mockgoose.

The model:

var Campaign = new Schema({
    //Schema here 
});

Campaign.statics.getOneById = function(id) {
    return this.findOne({_id: id }).populate('channels').populate('units');
};

The code under test:

function getCampaignById(id) {
    return Campaign.getOneById(id);
}

The test code:

var chai = require('chai'),
    chaiAsPromised = require('chai-as-promised'),
    mongoose = require('mongoose'),
    mockgoose = require('mockgoose'),
    Campaign = require('../src/campaigns/models/campaign-model'),
    Channel = require('../src/channels/models/channel-model'),
    Unit = require('../src/units/models/unit-model'),
    campaignRepo = require('../src/campaigns/lib/campaign-repository'),
    config = require('../scripts/services/config');

chai.use(chaiAsPromised);
chai.should();

before(function(done) {
    mockgoose(mongoose).then(function() {
        mongoose.connect(config.db.dbStr, function(err) {
            done(err);
        })
    })
});

describe('Campaign repository', function() {

    var fullCampaign = {
        country: {
            dst:1,
            timezone:'+02:00',
            code:'AX',
            name:'Åland Islands'},
        name: 'This is campaign name',
        startDate:'2017-02-19T22:00:00.000Z',
        endDate:'2017-02-27T22:00:00.000Z',
        creatives: ['creative'],
        units:[],
        channels:[],
        money: {
            action: {
                event: 'interaction_loaded',
                label: 'View'
            },
            currency: {
                code: 'USD',
                sign: '$'
            },
            budget: 11111,
            costPerAction: 2
        }
    };

    var newCampaign;

    it('should create a new campaign', function() {
         campaignRepo.create(fullCampaign).then(function(createdCampaign) {
            newCampaign = createdCampaign;
        });
    });

    it('should get the new campaign from the database', function() {
        return (campaignRepo.getCampaignById(newCampaign._id)).should.eventually.equal(newCampaign);
    });
});

The problem is that the last equality check hangs mocha:

  Campaign repository
    ✓ should create a new campaign
    1) should get the new campaign from the database


  1 passing (141ms)
  1 failing

And when doing the same tests on a non object,

return (campaignRepo.getCampaignById(scopeNewCampaign._id)).should.eventually.equal('just a string');

mocha just fails normally.

  Campaign repository
    ✓ should create a new campaign
    1) should get the new campaign from the database


  1 passing (141ms)
  1 failing

  1) Campaign repository should get the new campaign from the database:
     AssertionError: expected { Object ($__, isNew, ...) } to equal 'just a string'
dabn
  • 33
  • 1
  • 5

1 Answers1

0

Not sure if thats the root of your problem, but this is to long for a comment.

First, you don't return the promise in your first test case. Therefore mocha doesn't wait until your object is created. This might be the cause of the fail of your second test. So try this:

it('should create a new campaign', function() {
     return campaignRepo.create(fullCampaign).then(function(createdCampaign) {
        newCampaign = createdCampaign;
    });
});

Secondly, imo it's very bad style to make your tests dependend from each other. Its much cleaner, if every test case can be run on its own. Otherwise all your consecutive test fail if the first one errors and you don't see why. This might seem a bit much work on first setup, but it's def. worth in the long run. Otherwise you will find yourself getting confused of failing tests that are actually fine.

Johannes Merz
  • 3,252
  • 17
  • 33
  • Unfortunately your proposal doesn't work, and as i stated the problem is more than the test failing, it's the whole test suite just hangs the terminal. About your second point, you are absolutely correct, but since I'm just starting to write these tests and i've encountered this problem, I didn't design the tests completely. – dabn Feb 06 '17 at 15:51
  • do you have any database connection at all? – Johannes Merz Feb 06 '17 at 16:28
  • another thing i just noticed, as you comparing objects you need to use deep equal: `.should.eventually.deep.equal` – Johannes Merz Feb 06 '17 at 16:32