0

I am using ngx-bootstrap's (3.0.1) ModalService to show a modal dialog containing a component

this.modalRef = this.modalService.show(MyDialogComponent);

and I have this in my unit test (run by jest)

beforeEach(async(() => {
  TestBed.configureTestingModule({
    declarations: [MyComponent, MyDialogComponent],
    schemas: [CUSTOM_ELEMENTS_SCHEMA],
    providers: [MyService],
    imports: [
      ModalModule.forRoot(),
    ],
  })
  .compileComponents();
}));

The stubborn error tells me Can't resolve all parameters for BsModalService: (?, ?). The answers I was able to find were mentioning lack of a proper @Injectable() decorator, but this is obviously beyond my control and besides all it is irrelevant and misleading - the decorator is present in the source code of ngx-bootstrap.

I tried to explicitly provide all the components and services from the package (rather than ModuleWithProviders, but this didn't help either.

Running short of ideas.

Update 1

Tried commenting in and out

import 'core-js/es7/reflect';

in plyfills.ts. Doesn't seem to matter. Unless there is a Jest config setting associated with that that I am missing?

user776686
  • 7,933
  • 14
  • 71
  • 124
  • Did my answer help you? – Lucho Nov 06 '18 at 18:11
  • Regretfully not. I ended up ditching Bs dialog and wrote my own lightweight solution, based on ngrx store, no flaky services anymore. – user776686 Nov 07 '18 at 09:09
  • That strange even when i provided a working solution on stackblitz. Ah ok, maybe that could be possibly be conflicting with that setup of your app. – Lucho Nov 07 '18 at 09:19

2 Answers2

0

try to import core-js/es7/reflect in your polyfills.ts, it's needed to make your test work

import 'core-js/es7/reflect';
Fateh Mohamed
  • 20,445
  • 5
  • 43
  • 52
0

As the service from BsModalService dynamically populates the DOM (entryComponents) you can take use of BrowserDynamicTestingModule API by adding into the configureTestingModule:

beforeEach(async(() => {
TestBed.configureTestingModule({
    imports: [ ModalModule.forRoot() ],
    declarations: [ MyDialogComponent ],
}).overrideModule(BrowserDynamicTestingModule, {
  set: {
    entryComponents: [ HelloComponent ],
  }
}).compileComponents();

}));

trigger template elements(e.g. a button) with the dispatch API and then just check if it pops up in the DOM.

here's a stackblitz with a live example.

NOTE: As the ngx BsModalService populates the DOM as a sibling to the root node of angular i was not able to use the Angular API to select the modal element so instead i had to use DOM querySelector. If someone has a better way please comment so i can update

Lucho
  • 1,455
  • 1
  • 13
  • 25