Skip to content

error with DI in unit tests #278

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
vlio20 opened this issue Mar 5, 2016 · 9 comments
Closed

error with DI in unit tests #278

vlio20 opened this issue Mar 5, 2016 · 9 comments

Comments

@vlio20
Copy link

vlio20 commented Mar 5, 2016

I have created some services via ng g service <NAME>.
I have added the service to app.ts bootsrap:

import {bootstrap} from 'angular2/platform/browser';
import {AngularDayPickerApp} from './app/angular-day-picker';
import {CalendarHelper} from './app/services/calendar-helper/calendar-helper';
import {Utils} from './app/services/utils/utils';

bootstrap(AngularDayPickerApp, [
  CalendarHelper,
  Utils
]);

Running ng serveworks correctly and services are injected without any problems.
The issue happens when I am running ng test:

Failed: No provider for Utils! (CalendarHelper -> Utils)
Error: DI Exception

Should I do something in the karma configuration?

Here is the full stacktrace:

Chrome 48.0.2564 (Mac OS X 10.10.5) CalendarHelper Service should build correct month for any day of week FAILED
        Failed: No provider for Utils! (CalendarHelper -> Utils)
        Error: DI Exception
            at NoProviderError.BaseException [as constructor] (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:7351:21)
            at NoProviderError.AbstractProviderError [as constructor] (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:1649:14)
            at new NoProviderError (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:1673:14)
            at Injector._throwOrNull (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11547:15)
            at Injector._getByKeyDefault (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11592:19)
            at Injector._getByKey (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11540:21)
            at Injector._getByDependency (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11528:21)
            at Injector._instantiate (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11423:32)
            at Injector._instantiateProvider (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11395:21)
            at Injector._new (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11385:19)
            at InjectorDynamicStrategy.getObjByKeyId (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11263:42)
            at Injector._getByKeyDefault (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11586:33)
            at Injector._getByKey (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11540:21)
            at Injector.get (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11340:19)
            at /Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/testing.dev.js:1917:25
            at Array.map (native)
            at Array.map (/Users/vioffe/personal/angular-day-picker/node_modules/es6-shim/es6-shim.js:1113:14)
            at FunctionWithParamTokens.execute (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/testing.dev.js:1916:33)
            at TestInjector.execute (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/testing.dev.js:1864:17)
            at Object.<anonymous> (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/testing.dev.js:1978:44)
            at Object.<anonymous> (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/testing.dev.js:1997:11)
            at /Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/testing.dev.js:1986:15
            at Zone.run (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:1243:24)
            at zoneBoundFn (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:1220:26)
            at lib$es6$promise$$internal$$tryCatch (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:468:17)
            at lib$es6$promise$$internal$$invokeCallback (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:480:18)
            at lib$es6$promise$$internal$$publish (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:451:12)
            at /Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:123:10
            at Zone.run (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:1243:24)
            at zoneBoundFn (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:1220:26)
            at MutationObserver.lib$es6$promise$asap$$flush (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:262:10)
Chrome 48.0.2564 (Mac OS X 10.10.5) MonthBoard Component should ... FAILED
        Failed: No provider for CalendarHelper! (MonthBoard -> CalendarHelper)
        Error: DI Exception
            at NoProviderError.BaseException [as constructor] (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:7351:21)
            at NoProviderError.AbstractProviderError [as constructor] (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:1649:14)
            at new NoProviderError (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:1673:14)
            at Injector._throwOrNull (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11547:15)
            at Injector._getByKeyDefault (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11592:19)
            at Injector._getByKey (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11540:21)
            at Injector._getByDependency (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11528:21)
            at Injector._instantiate (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11423:32)
            at Injector._instantiateProvider (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11395:21)
            at Injector._new (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11385:19)
            at InjectorInlineStrategy.instantiateProvider (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:11149:28)
            at ElementDirectiveInlineStrategy.init (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:9081:20)
            at new AppElement (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:8771:24)
            at HostViewFactory.viewFactory_HostMonthBoard0 [as viewFactory] (viewFactory_HostMonthBoard:73:29)
            at AppViewManager_.createRootHostView (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:6461:34)
            at /Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2.js:12356:46
            at Zone.run (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:1243:24)
            at zoneBoundFn (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:1220:26)
            at lib$es6$promise$$internal$$tryCatch (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:468:17)
            at lib$es6$promise$$internal$$invokeCallback (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:480:18)
            at lib$es6$promise$$internal$$publish (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:451:12)
            at /Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:123:10
            at Zone.run (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:1243:24)
            at zoneBoundFn (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:1220:26)
            at MutationObserver.lib$es6$promise$asap$$flush (/Users/vioffe/personal/angular-day-picker/node_modules/angular2/bundles/angular2-polyfills.js:262:10)
Chrome 48.0.2564 (Mac OS X 10.10.5): Executed 4 of 4 (2 FAILED) (0.097 secs / 0.093 secs)
@vlio20 vlio20 changed the title DI in unit tests error with DI in unit tests Mar 7, 2016
@filipesilva
Copy link
Contributor

Heya, can you show me the failing test?

I believe this issue is not due to karma per se, but rather due to the test.

@vlio20
Copy link
Author

vlio20 commented Mar 10, 2016

@filipesilva, Here it is:

import {it,iit,describe,ddescribe,expect,inject,injectAsync, TestComponentBuilder,beforeEachProviders} from 'angular2/testing';
import {provide} from 'angular2/core';
import {CalendarHelper} from './calendar-helper';
import Moment = moment.Moment;
import MomentStatic = moment.MomentStatic;
import {Utils} from '../utils/utils';

describe('CalendarHelper Service', () => {

  beforeEachProviders(() => [CalendarHelper]);

  it('should build correct month for any day of week', inject([CalendarHelper, Utils], (service: CalendarHelper, utils: Utils) => {
    let dayOfMonth: Moment = moment('03-05-2016', 'MM-DD-YYYY');
    utils.range(0, 6).forEach((startDayOfWeek) => {
      let weeks: Moment[][] = service.getMonthWeeks(dayOfMonth, startDayOfWeek);
      expect(weeks.length).toEqual(6);
      weeks.forEach((week: Moment[]) => {
        expect(week.length).toEqual(7);
        expect(week[0].day()).toEqual(startDayOfWeek);

        week.forEach((day: Moment) => {
          expect(day.isSame(dayOfMonth, 'M'));
        });
      });
    });
  }));
});

Note that eve if I remove the Utils class I still getting issue with the CalendarHelper DI.

@filipesilva
Copy link
Contributor

I believe you will also need to add Utils to beforeEachProviders.

My understanding is that when you are unit testing a service/component/etc, you do not have the injector you have in your tree of components but rather an empty injector to which you can add providers via beforeEachProviders.

Thus, when trying to instantiate CalendarHelper, it searches the injector for Utils. Not finding it, you get the the error you have shown.

My understanding may be incorrect, but it is what I used when devising tests for routes. If you generate a route, you will find a test with custom mocks for services in the *-detail.component.spec.ts file.

@filipesilva
Copy link
Contributor

Try this (note Utils added in the array):

(...)
describe('CalendarHelper Service', () => {

    beforeEachProviders(() => [Utils, CalendarHelper]);

(...)

@vlio20
Copy link
Author

vlio20 commented Mar 10, 2016

@filipesilva thanks, it seems to solve the issue with the injections.
One more question if I may ask, should I include somewhere the 3rd party libs in my tests? I have added momentjs to my project to the apps/assets folder, as suggested by the developing team, until there will be official support for 3rd party libs.

@filipesilva
Copy link
Contributor

I'm glad it worked!

I don't have a definite answer to the 3rd party libs question at the moment, unfortunately. We are working on it, but at the moment the best approach is the one in #274.

@RaghuRangaraj
Copy link

Error: No provider for name!
I am getting above error in angular 2 rc5 version. Any help on the same is appreciated.

@filipesilva
Copy link
Contributor

@RaghuRangaraj the Angular docs have been updated to include extensive testing documentation: https://angular.io/docs/ts/latest/guide/testing.html

This documentation is for Angular 2.0.0 final, so I advise you to update.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants