lathonez / clicker

Ionic 2 + @angular/cli Seed Project : Angular2 + Typescript + Karma + Protractor + Travis
http://lathonez.com/2018/ionic-2-unit-testing/
MIT License
430 stars 137 forks source link

testing AppComponent : No provider for TransitionController! #229

Closed swaheed2 closed 7 years ago

swaheed2 commented 7 years ago

Is it possible to test the functions in the AppComponent?

TransitionController is private in ionic, so I can't import that.

app.component.spec.ts

describe('Pages: AppComponent', () => {

    beforeEach(async(() => TestUtils.beforeEachCompiler([AppComponent], [
        { provide: Platform, useClass: PlatformMock },
        { provide: Config, useClass: ConfigMock },
        { provide: AppService, useClass: AppService },
    ]).then(compiled => {
        fixture = compiled.fixture;
        instance = compiled.instance;
    })));

    it('should create the app component', async(() => {
        expect(instance).toBeTruthy();
    }));
});

test.ts

export class TestUtils {

  public static beforeEachCompiler(components: Array<any>, providers: Array<any>): Promise<{ fixture: any, instance: any }> {
    return TestUtils.configureIonicTestingModule(components, providers)
      .compileComponents().then(() => {
        let fixture: any = TestBed.createComponent(components[0]);
        return {
          fixture: fixture,
          instance: fixture.debugElement.componentInstance,
        };
      });
  }

  public static configureIonicTestingModule(components: Array<any>, providers: Array<any>): typeof TestBed {
    return TestBed.configureTestingModule({
      declarations: [
        ...components,
      ],
      providers: [
        ...providers,
        App, Form, Keyboard, DomController, MenuController, NavController, GestureController
      ],
      imports: [
        IonicModule //.forRoot(AppComponent)
      ],
    });
  }

  // http://stackoverflow.com/questions/2705583/how-to-simulate-a-click-with-javascript
  public static eventFire(el: any, etype: string): void {
    if (el.fireEvent) {
      el.fireEvent('on' + etype);
    } else {
      let evObj: any = document.createEvent('Events');
      evObj.initEvent(etype, true, false);
      el.dispatchEvent(evObj);
    }
  }
}

Error:

FAILED TESTS:
  Pages: AppComponent
    × should create the app component
      Chrome 56.0.2924 (Windows 10 0.0.0)
    Error: No provider for TransitionController!
        at NoProviderError.BaseError [as constructor] (webpack:///~/@angular/core/src/facade/errors.js:24:0 <- src/test.ts:9307:34)
        at NoProviderError.AbstractProviderError [as constructor] (webpack:///~/@angular/core/src/di/reflective_errors.js:41:0 <- src/test.ts:56724:16)
        at new NoProviderError (webpack:///~/@angular/core/src/di/reflective_errors.js:72:0 <- src/test.ts:56755:16)
        at ReflectiveInjector_._throwOrNull (webpack:///~/@angular/core/src/di/reflective_injector.js:758:0 <- src/test.ts:105489:19)
        at ReflectiveInjector_._getByKeyDefault (webpack:///~/@angular/core/src/di/reflective_injector.js:786:0 <- src/test.ts:105517:25)
        at ReflectiveInjector_._getByKey (webpack:///~/@angular/core/src/di/reflective_injector.js:749:0 <- src/test.ts:105480:25)
        at ReflectiveInjector_.get (webpack:///~/@angular/core/src/di/reflective_injector.js:558:0 <- src/test.ts:105289:21)
        at TestBed.get (webpack:///~/@angular/core/bundles/core-testing.umd.js:814:0 <- src/test.ts:22690:67)
        at CompiledTemplate.proxyViewClass.AppView.injectorGet (webpack:///~/@angular/core/src/linker/view.js:109:0 <- src/test.ts:106031:45)
        at CompiledTemplate.proxyViewClass.DebugAppView.injectorGet (webpack:///~/@angular/core/src/linker/view.js:351:0 <- src/test.ts:106273:49)
    Error: Uncaught (in promise): Error: Error in ./AppComponent class AppComponent - inline template:35:0 caused by: No provider for TransitionController!
        at resolvePromise (webpack:///~/zone.js/dist/zone.js:468:0 <- src/test.ts:134725:31)
        at resolvePromise (webpack:///~/zone.js/dist/zone.js:453:0 <- src/test.ts:134710:17)
        at webpack:///~/zone.js/dist/zone.js:502:0 <- src/test.ts:134759:17
        at ZoneDelegate.invokeTask (webpack:///~/zone.js/dist/zone.js:265:0 <- src/test.ts:134522:35)
        at ProxyZoneSpec.onInvokeTask (webpack:///~/zone.js/dist/proxy.js:103:0 <- src/test.ts:97021:39)
        at ZoneDelegate.invokeTask (webpack:///~/zone.js/dist/zone.js:264:0 <- src/test.ts:134521:40)
        at Zone.runTask (webpack:///~/zone.js/dist/zone.js:154:0 <- src/test.ts:134411:47)
        at drainMicroTaskQueue (webpack:///~/zone.js/dist/zone.js:401:0 <- src/test.ts:134658:35)
lathonez commented 7 years ago

Hey,

Basically no. Ionic are aware of the issue: https://github.com/driftyco/ionic/issues/10264.

My advice is to move as much as possible out of AppComponent, and test what you need to in AppComponent without compiling it: https://github.com/lathonez/clicker/blob/master/src/app/app.spec.ts

Thanks