Promise rejected during <MY_COMPONENT_TEST>: Cannot call `render` without having first called `setupRenderingContext`

I get this strange error message when I tried to run a test for my component. Promise rejected during “MY_COMPONENT_TEST”: Cannot call render without having first called setupRenderingContext. I followed what has been mentioned in the ember component test documentation. I have called setupRenderingTest(hooks). But still getting this weird error message when running tests. But the test works fine when I remove rendering the component using render method. I also get the following error messages Promise rejected before “MY_COMPONENT_TEST”: appContainer is undefined, Promise rejected before “MY_COMPONENT_TEST”: owner is undefined, Promise rejected before “MY_COMPONENT_TEST”: right-hand side of ‘in’ should be an object, got undefined

I think this is the key. Something in your test setup is throwing an exception, and that’s stopping the test setup before it gets to setupRenderingContext, which is why you see the other error.

It’s not clear which error is the first one, but it’s probably the first one you should investigate. All the others could be fallout from that one.

1 Like

Yes I found an error and may be due to this why ember fails to get a context to render the component when I run component test.

export function initialize( application) {
  let appContainer = application.__container__;
  console.log("AppContainer is", appContainer); //undefined
}

export default {
  initialize
};

This is my initializer file where when I access the __container__ of the application I get undefined. This code is part of an addon.

That addon is using some old private API. It should probably be using getOwner(application) instead, but I’d need to see more to know for sure.

It has only been 2 months that I started learning Ember. I still don’t understand how the EmberJs works internally. I read the documentation and found that initializer recieves application and instance-intializer recieves applicationInstance. I don’t understand the difference between application and applicationInstance. And also what the __container__ is.

The snippet I added above is part of a codebase that I was asked to learn. Could you please tell me what all these application, applicationInstance and __container__ really are.

In the addon the __container__ is used to access a particular service and to call an intialize method on the service. And this code is present in the initializer folder of the addon.

It sounds like you are stuck trying to update an addon that is pretty far out-of-date, which can be frustrating when you’re first learning.

__container__ is an old private API. It’s not a safe thing to use. The equivalent public API for getting a service from an instance-initializer is applicationInstance.lookup('service:your-service-name').

You should use an instance-initializer for this, because instance-initializers have access to the actual state of your running application, including things like the instances of your services.

initializers on the other hand can only really address classes and not instances. The reason they are distinct from instance-initializers is mostly for server-side rendering. Ember divides the work into these two phases because some of the work (the initializers) can be done once and then shared across all users who hit the server, whereas some other work (the instance-initializers) needs to be done per user.

There are very narrow use cases for initializers. You almost always don’t need one. There are more use cases for instance-initializers, but even those are really only relevant in addons. Apps have better alternatives (like the application route, which gives you similar timing while also giving better control over asynchrony).

2 Likes

The __container__ can be accessed during component testing without error when the autoboot is true. But I get a different error

Assertion Failed: You cannot use the same root element (DIV) multiple times in an Ember.Application

What could be the reason for this error?

It’s because you set autoboot to true. That means your real application is trying to run at the same time the test suite is running. That will lead to much confusion.

This is a problem of timing. Initializers can’t access services in modern ember because they run too early. By autobooting the real application before the tests, that changes the timing and ensures a container will exist. But it’s still not a good idea – in particular you will probably have two different containers.

The fix is to change the addon to use an instance-initializer and not an initializer.

Thankyou ef4, I converted the initializer to an instance-intializer and now its working fine.

1 Like