Stubbing container when testing ember addon helper

Continuing the discussion from Best Practices: accessing app config from addon code:

I’m attempting to test an addon that needs to reference the parent app’s config, in order to determine the environment that it’s running in. I’m attempting to stub out the container’s lookupFactory method, but referencing this.container within the helper during test is undefined, although everything works fine in development.

I’m attempting to use Sinon in a similar way to how ember-simple-auth is within their suite. Here’s what my tests/unit/helpers/data-test-test.js file looks like:

import {
  dataTest
} from '../../../helpers/data-test';
import { module, test } from 'qunit';

module('Unit | Helper | data test', {
  beforeEach: function(){
    this.container = { lookupFactory: function() {} };
    let env = { environment: 'test' };
    let containerStub = sinon.stub(this.container, 'lookupFactory');
    containerStub.withArgs('config:environment').returns(env);
  }
});

test('it works', function(assert) {
  var result = dataTest(42);
  assert.ok(result);
});

And my helper file:

import Ember from 'ember';

export function dataTest(identifier) {
  let env = this.container.lookupFactory('config:environment');
  if(env.environment === 'test') {
    return `data-test="${identifier}"`;
  } else {
    return undefined;
  }
}

export default Ember.HTMLBars.makeBoundHelper(dataTest);

Is there a reason the container is not available during test? Do I need an application instance in order to test this type of behavior?

Here’s the corresponding stack trace, which shows the container being undefined:

Unit | Helper | data test: it works
    ✘ Died on test #1     at http://localhost:7357/assets/test-support.js:2809
        at http://localhost:7357/assets/test-support.js:16434
        at http://localhost:7357/assets/dummy.js:262
        at http://localhost:7357/assets/vendor.js:150
        at tryFinally (http://localhost:7357/assets/vendor.js:30)
        at http://localhost:7357/assets/vendor.js:156
        at http://localhost:7357/assets/test-loader.js:29
        at http://localhost:7357/assets/test-loader.js:21
        at http://localhost:7357/assets/test-loader.js:40
        at http://localhost:7357/assets/test-support.js:5578: 'undefined' is not an object (evaluating 'this.container.lookupFactory')

I think it’s going to change from this.container to a parameter passed in to the helper: env.data.view.container. That will make it easier to mock.

In the meantime I did this:

var container = new Ember.Container();
container.register('foo:bar', FooBar);
var context = {
  container: container
};
var fooBarHelper = function() {
  return fooBar.apply(context, arguments);
};

and then test the wrapper instead of the helper itself.

Thanks for the example @amk, but it looks like your example is already out of date on canary. See this issue. Hoping @wycats can provide more details on how to access this data in the future. This gives people literally a few weeks to figure out how their plugins won’t break when they upgrade. Ugh.

1 Like