javascriptember.jsdependency-injectionember-testingember-components

Ember.js component integration test: How to work with global injections and nested components?


Scenario: I want to integration test component A using a real service my-service. I have an initializer that is globally injecting the service into all components: application.inject('component', 'myService', 'service:my-service');. Component A uses Component B in its template, and they both use myService in their templates.

How do I recreate the global injection? There is no full application, so I can't import and run the real initializer because I don't have the parameter required. this.inject.service doesn't work because it injects it into test context, not global application context.

I could change all my components' templates to chain the service all the way down: {{b-component myService=myService}}, and then

this.render(hbs`{{a-component myService=myService}}`);

But that is a last resort. I could also get rid of the global injection and manually inject in every component. That is also a last resort.

I've tracked down talk of this issue to https://github.com/emberjs/ember.js/issues/12277. It was almost implemented, but then closed in favor of Grand Testing Unification https://github.com/emberjs/rfcs/pull/119. Are there any now solutions while we wait for Grand Testing Unification?


Solution

  • With hints from https://stackoverflow.com/users/1157494/robert-jackson, I was able to find the missing piece. You are able to lookup the owner in test context, which is the missing parameter you need to feed to an initializer:

    import { initialize } from 'my-app/initializers/my-initializer';
    
    // ...
    
    beforeEach() {
      initialize(Ember.getOwner(this));
    }
    

    Now all your components with have the global injections they require!