Search code examples
angularkarma-runnerangular2-modal

Angular2-Modal won't run in Karma


I have angular2-modal running fine in my angular 2 app. However, I am having issues testing via Karma. I have set up my test bed with

beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [
                HttpModule
            ],
            providers: [
                ApiService,
                MockBackend,
                UiComponentService,
                BaseRequestOptions,
                AlertCenterService,
                {
                    provide: Http,
                    useFactory: (backend: any, options: any) => new Http(backend, options),
                    deps: [MockBackend, BaseRequestOptions]
                },
                Overlay,
                OverlayRenderer,               
                Modal
            ]
        });
    });

However, I get the strange DI Error:

Error: No provider for Modal$$1!
Error: DI Error

The UiComponentService is where I use the modal. Tests were working prior to adding the modal. I can't find a reference to Modal with $$1 appended anywhere, and I don't understand where it is coming from.


Solution

  • I imagine the Modal is also missing dependencies. I've seen errors like this where the error only explains the problem with the looked up dependency (the service) and not the dependencies it relies on (even though that's the root cause). How are you configuring it in the main app? Is it just by adding the Modal to the providers, or are you importing some Module.forRoot(). If the latter, you should do the same for the test

    BUT...

    Do you really need to full working Modal for a unit test. It might just be better to mock it because all you need to test is the behavior of your service. And I'm assuming all the service does is call some method on the Modal. So that's all you really need to test

    let modal;
    
    beforeEach(() => {
      modal = { openModal: jasmine.createSpy('openModal') }
    
      ...
      providers: [
        { provide: Modal, useValue: modal }
      ]
    })
    
    it('', () => {
      doSomething()
    
      expect(modal.openModal).toHaveBeenCalledWith(whatever);
    })
    

    This is just assuming Modal has a methed openModal. All you really need to test is that service calls the openModal method, as that is the behavior of the service being tested.