Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Register.resolve should prioritize manually registered classes over the resolver #11174

Closed
igorT opened this issue May 15, 2015 · 10 comments
Closed

Comments

@igorT
Copy link
Member

igorT commented May 15, 2015

Currently there is no way to replace an factory that comes from a resolver.
Consider the case in testing where:

   import adapter from 'adapters/my-adapter';
   var TappedAdapter = MyAdapter.extend({ ajax..... });
  container.unregister('adapter:my-adapter');
  container.register('adapter:my-adapter', TappedAdapter);

This currently does not work, because resolve prioritizes the resolver over the manually registered class https://github.com/emberjs/ember.js/blob/master/packages/container/lib/registry.js#L752
We can fix this by either switching the order, or caching the result of the manually registered class here https://github.com/emberjs/ember.js/blob/master/packages/container/lib/registry.js#L216

@igorT
Copy link
Member Author

igorT commented May 15, 2015

cc @dgeb

@mixonic
Copy link
Member

mixonic commented May 15, 2015

This was intentional. It allowed for ember and ember-data to register a default module that could be supplanted by a user-provided one. /cc @stefanpenner

@SaladFork
Copy link
Contributor

If this is intentional there should be another mechanism for replacing registrations in tests. We currently use a service to handle our atypical back-end that all our adapters take advantage of. Stubbing this out requires private APIs.

I found the solution via the discuss thread which points to more information and a workaround in a StackOverflow post. They recommend a stubResolver and stubLookup approach which manually access the container's registry and cache.

As far as I can tell this is the best way to do it today, given it is done this way in @stefanpenner's ember-jobs.

(cc @rondale-sc who is using this approach in ember-weekend)

@mixonic
Copy link
Member

mixonic commented May 15, 2015

@SaladFork I don't disagree there is an issue. We feel this pain ourselves. Despite this, at a technical level I don't think the solution is as easy as what igor describes. Perhaps there is something we can do in the timeframe of the next few weeks before 2.0 to make sure things are better moving forward. I'd like to hear stef's thoughts but he is vacationing this week.

For what its worth, our approach is to mock the 3rd party APIs. We find this to be a good parallel to how AJAX is stubbed (at the XHR object level) and acceptance tests work (by triggering user interactions). It means you acceptance tests truly test all of your own code (leaving more isolating tests to integration and unit testing). You can find several of our mocks in this project though everyone will have different requirements.

@SaladFork
Copy link
Contributor

@mixonic thanks for your reply and discussion on IRC. Though stubbing at the XHR level is more difficult (our API makes requests to one endpoint and long-polls another for responses), I agree it is a more true test.

Two points from the IRC discussion:

  • @mixonic suggested dynamically choosing which service gets injected at run-time using a property on the environment (ENV.apiService = 'my-service' normally, tests override to 'my-mock-service', then Ember.inject.service(ENV.apiService). Might also be able to do this in the service file itself to avoid importing ENV everywhere.
  • @chrism suggested a technique highlighted in his blog post where you write an initializer and have it inject the normal service by default, but allow passing in an alternate service (used in testing). This does require naming the service differently to avoid a conflict with the resolver.

Of course these techniques can be applied to adapters or other non-services. Would be nice to see a recommended way of stubbing such things out.

@igorT
Copy link
Member Author

igorT commented May 15, 2015

@mixonic for testing, currently application.registry is the fallback registry so even solving this wouldn't fix it. However if we passed a TestRegistry it would solve this problem without having to change register.

@igorT
Copy link
Member Author

igorT commented May 15, 2015

Otherwise Ember/Ember-Data providing a fallback seems like a case for regsisterFallback?

@olivierlesnicki
Copy link

How do one achieve the same result pre 2.x.x ?

@rwjblue
Copy link
Member

rwjblue commented Oct 6, 2015

Support was added to ember-test-helpers a little while back (in emberjs/ember-test-helpers#96), which supports Ember 1.11 and above.

@olivierlesnicki
Copy link

@rwjblue sadly I'm writing acceptance tests... this.registry is not defined.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants