How to spy on a Falcor Data Model constructor in Jasmine 1

78 views Asked by At

I am trying to mock the constructor returned by require('falcor'); I have two routes and one calls the other route using var dataModel = new falcor({source: this});

Code looks like so

var falcor = require('falcor');
module.exports = {
    route: 'items',
    get: function (pathSet) {
        var dataModel = new falcor({source: this});
        var ids = '1';
        dataModel.get('itemIds', ids).then(function (response) {
            // Code I can't get to in Jasmine 1.x tests
        });
    }
}

I want the constructor to return a spy so I can call Promise.resolve and send back mock data for testing purposes. I'm not sure how to do this without moving the call into another module that I can mock separately. I think some questions that may help me here are

  1. Where do I find the constructor functions defined by modules like falcor? I have tried looking into the 'global' object but have had no luck. If I did find this constructor, could I just replace it with a spyOn(global, 'falcor').andReturn(/* object with a mocked get method*/); ?
  2. Is there a better way that makes testing easier to call a route from inside another route?

Thanks for any help.

1

There are 1 answers

0
James Conkling On

To start w/ question 2: yes, to get data from another route, return refs to that route. Don't instantiate another model w/i the route. E.g.

const itemsRoute = {
  route: 'items[{keys:indices}]',
  get(pathSet) {
    // map indices to item ids, likely via DB call
    // in this case, SomeDataModel handles network requests to your data store and returns a promise
    return SomeDataModel.getItemsByIndices(pathSet.indices)
      .then(ids => ids.map((id, idx) => ({
        path: ['items', pathSet.indices[idx]],
        value: {
          $type: 'ref',
          value: ['itemById', id]
        }
      })));
  }
};

const itemByIdRoute = {
  route: 'itemById[{keys:ids}].name',
  get(pathSet) {
    return new Promise((resolve) => {
      resolve(pathSet.idx.map(id => ({
        path: ['itemById', id, 'name'],
        value: {
          $type: 'atom',
          value: `I am item w/ id ${id}`
        }
      })));
    });
  }
};

When a request comes in for (e.g.) [items, 2, name], it will hit the first items route, resolve [items, 2] to [itemById, someId], and resolve the remaining name key in the itemsById route.

As for question 1: rather than mocking falcor, just mock whatever you are using to make the remote call to your data source. In the above case, just mock SomeDataModel