0
votes

I'm facing some issue with one of my component integration test. To explain briefly, my component uses a sub-component which uses some ember-can ability to select options to display.

The abilities are relying on a controller to know which is the current project and so what are the permissions of the user. So in our app.js file, we have something like that:

application.inject('ability', 'projectController', 'controller:project');

Of course, when doing the integration test for the component, the ability is unable to find the controller, nor the project and so always consider the user does not have the required permission.

I tried so far stuff like that:

this.register('controller:project', Ember.Object.create({
  project: this.project
}));
this.inject.controller('controller:project', {as: 'projectController'});

But this does not have any impact on the abilities (the test documentation shows how to inject services but is pretty poor on the controller injection).

Does anyone have a good idea on how to solve that issue ?

Best regards, Vincent

1
You can inject controller only in another controller by doing Ember.inject.controller('controllername') and pass down required properties to component. am not sure what you are looking is possible let us wait for the answer. - Ember Freak

1 Answers

0
votes

What you are trying to achieve seems to be stubing of something in your application for the tests purposes. Given that you are doing a component integration test i would assume that you do that via moduleForComponent of ember-qunit which relies on TestModuleForComponent from ember-test-helpers package. This module would be setup differently depending on the combination of needs:[...] , integration: true/false and unit: true/false properties that are set on it. However if you are doing integration test either by setting integration: true or by specifying needs: ['some'] you can access the owner from inside your test scope like this:

test('my test', function(assert) {
    const owner = Ember.getOwner(this);
});

after you get the owner you can do lookup on it. For your case you can also use container with its register and unregister like so:

test('my test', function(assert) {
    this.container.unregister('controllers:my-controller');
    this.container.register('controllers:my-controller', ActualController.extend({
        someStubbedProp: 'value'
    }), {instantiate: false});
});

Please note that if you are dealing with singleton objects (like i.e. adapters) you are specifying {instantiate: false} to make sure they are not instantiated on registration time as they would be instantiated on app boot.

You can use the same technique to "inject" the controller into anything you want in your app. However this technique would not actually really inject one thing into the other but it would allow to access i.e. controller via the property you are stubbing:

test('my test', function(assert) {
     this.container.unregister('controllers:my-controller');
     this.container.register('controllers:my-controller', ActualController.extend({
         someStubbedInjection: Ember.computed({
             get(){
                 return Ember.getOwner(this).lookup('controller:some-other-controller-you-want-to-access');
             }
         })
     }), {instantiate: false});
 });

After that by accessing the someStubbedInjection prop on ActualController you would gain access to it.