angular: ComponentFactoryResolver is not aware of components compiled via TestBed
The ComponentFactoryResolver
has an internal map containing factories for components that have been compiled.
However, when TestBed compiles components declared in the DynamicTestModule
, the factories are stored in the TestBed’s internal _moduleWithComponentFactories
. These factories are never made known to the ComponentFactoryResolver
, so any tests that use the resolver to create a component declared in the test module will fail with Error: No component factory found for YourTestComponent
.
As a workaround, you can simply create a real @NgModule
in which to declare your test components and import that into the test module.
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Reactions: 22
- Comments: 36 (10 by maintainers)
Commits related to this issue
- docs(core): usage example for `TestBed.overrideModule()` Add an usage example for overriding an NgModule that is imported into the testing module. Closes #10760, #12079 — committed to dherges/angular by dherges 7 years ago
- docs(core): usage example for `TestBed.overrideModule()` Add an usage example for overriding an NgModule that is imported into the testing module. Closes #10760, #12079 — committed to dherges/angular by dherges 7 years ago
Please, do. It’s very inconvenient to configure
entryComponents
in tests now. I use this workaround at the moment (not sure if it’s correct way, but it works at least):They are not treated as entryComponents, otherwise the ComponentFactoryResolver would know them.
The ComponentFactoryResolver is only using entryComponents. The TestBed.createComponent method is not using the ComponentFactoryResolver nor the entryComponents of any module.
We should probably add entryComponents to configureTestingModule. Then the workaround you mentioned above of creating a temporary NgModule would not be needed any more… On Thu, Aug 18, 2016 at 5:35 PM Jeremy Elbourn notifications@github.com wrote:
I had meant to say that the
declarations
of the test module are meant to be treated asentryComponents
, and the fact that they’re not causes this bug. @IgorMinar is that the intention with the testing module?@tbosch
configureTesitngModule
doesn’t have anentryComponents
property- all of itsdeclarations
are automatically treated asentryComponents
.Can anyone share an example of how to test the MdDialog please… I am having issues testing the mdDialog with my code. I tried the looking into the code of Angular material 2 but I cant get it to work (maybe I am not understanding the example).
Needs investigation and we will propose a solution here.
It worked in the end for me @LOZORD
Here is a full gist of it, using a shared module pattern.
https://gist.github.com/ReneVallecillo/24e980c2a8442d9daaf187debd2d4369
Maybe @fallXone could use it.
Ignore js extension, it should be ts but it seems gist has no support of typescript
Importing
MdDialogModule
should fix that error.This worked for me:
@renevall did you tried like below?
in your configureTestingModule,
I have a very similar issue in where I need to declare a component dynamically within a featured module. My featured module which is loaded async when route is visited looks as follows:
I have another SharedModule where I import most of my site wide components most of them are entryComponents. I then have a Builder Service that is able to dynamically create a factory for each entryComponents using the ComponentFactory which works great for all components defined in the Shared and Main module but for the DynamicComponent that is only loaded with the dynamic module I get
No component factory found for DynamicComponent. Did you add it to @NgModule.entryComponents?
even though it is obviously defined in the entryComponents. Using the component statically in the FeaturedComponent template works but not when trying to create it dynamically.@LOZORD Could you provide a code, I keep getting
@allenhwkim For dynamically creating a component with the ComponentFactoryResolver you need to have the component declared in the entryComponents section. At least that’s my understanding and my tests confirmed this.
Having to declare the components I want to dynamically create in the @NgModule’s entryComponents section is a huge regression from my point of view. I used the DynamicComponentLoader and then the ComponentResolver and they both worked like a charm, but this new way of doing it it’s really not dynamic anymore and kind of beats the purpose if I have to “hardcode” the list of the components I want to dynamically create… this really broke our app, big way…
Tests that rely on ComponentFactoryResolver to be filled correctly need to declare “entryComponents” via configureTestModule (or import a module that does so). This way you can test that your module is correct / test how users would use your module.
The internal map in the test module should never go into the ComponentFactoryResolver as it makes all components entryComponents, which is not the case in actual apps.
On Sat, Aug 13, 2016 at 12:00 AM Jeremy Elbourn notifications@github.com wrote: