angular-redux / store

Angular 2+ bindings for Redux
MIT License
1.34k stars 202 forks source link

No provider for NgRedux during unit test #371

Closed malaugrim closed 7 years ago

malaugrim commented 7 years ago

Hello. I am getting a dependency injection error during component unit test. The test and component are really simple:

@Component({
    selector: 'summary-component',
    templateUrl: 'summary.template.html',
})
export class SummaryComponent implements OnDestroy {
    @select('order')
    private order$: Observable<Order>;

    @select(state => getCurrentProject(state.order))
    private currentProject$: Observable<Project>;

    private order: Order;
    private subscription: Subscription;

    constructor(private actions: OrderActions) {
        this.subscription = this.order$.subscribe(order => this.order = order);
    }

    ngOnDestroy(): void {
        if (this.subscription) {
            this.subscription.unsubscribe();
        }
    }

    navigateToAuditTeam() {
        this.actions.goToNextStep(this.order);
    }
}

The test is following:

describe('', () => {

    let fixture: ComponentFixture<SummaryComponent>;

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [NgReduxTestingModule, AccordionModule, SharedModule],
            declarations: [SummaryComponent, OrderDataComponent, OrderLocationsComponent, AuditTypesListingComponent],
        }).compileComponents();

        MockNgRedux.reset();
    });

    it('should pass', () => {
        fixture = TestBed.createComponent(SummaryComponent);
    })
});

Is this an issue, or am I doing something wrong here ?

SethDavenport commented 7 years ago

Hmm your code looks reasonable unless I'm missing something. What toolchain are you using? @angular/cli or something custom?

malaugrim commented 7 years ago

Hi Seth. Thank you for your reply. Yes I am using angular cli

SethDavenport commented 7 years ago

ok I'll take a look this afternoon

SethDavenport commented 7 years ago

What specific error are you getting? Can you paste the stack trace from karma in here? Just want to see which specific class is triggering it.

Do you need to add OrderActions to the providers list in your TestBed.configureTestingModule?

malaugrim commented 7 years ago

This is the error message I'm getting:

Error: No provider for NgRedux!
        Error: DI Error
            at NoProviderError.ZoneAwareError (webpack:///~/zone.js/dist/zone.js:958:0 <- src/polyfills.ts:4950:33)
            at NoProviderError.BaseError [as constructor] (webpack:///~/@angular/core/src/facade/errors.js:22:0 <- src/test.ts:41647:16)
            at NoProviderError.AbstractProviderError [as constructor] (webpack:///~/@angular/core/src/di/reflective_errors.js:54:0 <- src/test.ts:91057:16)
            at new NoProviderError (webpack:///~/@angular/core/src/di/reflective_errors.js:116:0 <- src/test.ts:91119:16)
            at ReflectiveInjector_.Array.concat.ReflectiveInjector_._throwOrNull (webpack:///~/@angular/core/src/di/reflective_injector.js:485:0 <- src/test.ts:130834:19)
            at ReflectiveInjector_.Array.concat.ReflectiveInjector_._getByKeyDefault (webpack:///~/@angular/core/src/di/reflective_injector.js:524:0 <- src/test.ts:130873:25)
            at ReflectiveInjector_.Array.concat.ReflectiveInjector_._getByKey (webpack:///~/@angular/core/src/di/reflective_injector.js:456:0 <- src/test.ts:130805:25)
            at ReflectiveInjector_.Array.concat.ReflectiveInjector_.get (webpack:///~/@angular/core/src/di/reflective_injector.js:325:0 <- src/test.ts:130674:21)
            at DynamicTestModuleInjector.get (/DynamicTestModule/module.ngfactory.js:149:104)
            at DynamicTestModuleInjector.getInternal (/DynamicTestModule/module.ngfactory.js:262:52)
            at DynamicTestModuleInjector.Array.concat.NgModuleInjector.get (webpack:///~/@angular/core/src/linker/ng_module_factory.js:139:25 <- src/test.ts:91992:44)
            at TestBed.get (webpack:///~/@angular/core/bundles/core-testing.umd.js:826:0 <- src/test.ts:27172:51)
            at CompiledTemplate.proxyViewClass.Array.concat.AppView.injectorGet (webpack:///~/@angular/core/src/linker/view.js:152:0 <- src/test.ts:131609:45)
            at CompiledTemplate.proxyViewClass.Array.concat.DebugAppView.injectorGet (webpack:///~/@angular/core/src/linker/view.js:580:0 <- src/test.ts:132037:49)
            at CompiledTemplate.proxyViewClass.View_SummaryComponent_Host0.createInternal (/DynamicTestModule/SummaryComponent/host.ngfactory.js:15:71)

When I added provider for OrderActions, I get the following error:

TypeError: Cannot read property 'select' of undefined
            at SummaryComponent.getter [as order$] (webpack:///~/ng2-redux/lib/decorators/select.js:23:0 <- src/test.ts:140151:47)
            at new SummaryComponent (webpack:///src/app/process/chapter-1/0-order-summary/summary.component.ts:24:27 <- src/test.ts:138680:33)
            at new Wrapper_SummaryComponent (/DynamicTestModule/SummaryComponent/wrapper.ngfactory.js:7:18)
            at CompiledTemplate.proxyViewClass.View_SummaryComponent_Host0.createInternal (/DynamicTestModule/SummaryComponent/host.ngfactory.js:15:32)
            at CompiledTemplate.proxyViewClass.Array.concat.AppView.createHostView (webpack:///~/@angular/core/src/linker/view.js:108:0 <- src/test.ts:131568:21)
            at CompiledTemplate.proxyViewClass.Array.concat.DebugAppView.createHostView (webpack:///~/@angular/core/src/linker/view.js:564:0 <- src/test.ts:132024:52)
            at ComponentFactory.Array.concat.ComponentFactory.create (webpack:///~/@angular/core/src/linker/component_factory.js:202:0 <- src/test.ts:56354:25)
            at initComponent (webpack:///~/@angular/core/bundles/core-testing.umd.js:865:0 <- src/test.ts:27214:53)
            at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:330:0 <- src/polyfills.ts:4322:26)
            at ProxyZoneSpec.Array.concat.ProxyZoneSpec.onInvoke (webpack:///~/zone.js/dist/proxy.js:79:0 <- src/test.ts:119670:39)
            at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:329:0 <- src/polyfills.ts:4321:32)
            at Object.onInvoke (webpack:///~/@angular/core/src/zone/ng_zone.js:273:0 <- src/test.ts:43312:37)
            at ZoneDelegate.invoke (webpack:///~/zone.js/dist/zone.js:329:0 <- src/polyfills.ts:4321:32)
            at Zone.run (webpack:///~/zone.js/dist/zone.js:126:0 <- src/polyfills.ts:4118:43)
            at NgZone.Array.concat.NgZone.run (webpack:///~/@angular/core/src/zone/ng_zone.js:142:42 <- src/test.ts:43181:62)
SethDavenport commented 7 years ago

I tried to repro the issue in the context of the example-app and couldn't, although I had to make up a few details.

Just for the sake of paranoia: what version of @angular/cli are you using? And what version of @angular-redux/store?

I see a reference in that stack trace to ng2-redux (which is the old package name) so that's unexpected.

malaugrim commented 7 years ago

I am using angular-cli 1.0.0 and @angular-redux/store 6.2.0. Below are the dependencies from my package.json file:

"dependencies": {
        "@angular/common": "^2.4.6",
        "@angular/compiler": "^2.4.6",
        "@angular/core": "^2.4.6",
        "@angular/forms": "^2.4.6",
        "@angular/http": "^2.4.6",
        "@angular/platform-browser": "^2.4.6",
        "@angular/platform-browser-dynamic": "^2.4.6",
        "@angular/router": "^3.4.6",
        "@ngx-translate/core": "^6.0.0",
        "@ngx-translate/http-loader": "0.0.3",
        "angular-2-dropdown-multiselect": "^0.4.1",
        "angular2-datatable": "^0.5.3",
        "angular2-ui-switch": "^1.2.0",
        "class-transformer": "^0.1.6",
        "core-js": "^2.4.1",
        "immutable": "^3.8.1",
        "ng2-bootstrap": "^1.3.3",
        "@angular-redux/store": "^6.2.0",
        "redux": "^3.6.0",
        "redux-thunk": "^2.2.0",
        "reflect-metadata": "^0.1.10",
        "rxjs": "^5.0.1",
        "ts-helpers": "^1.1.1",
        "typed-immutable-record": "0.0.6",
        "zone.js": "^0.7.7"
    },
    "devDependencies": {
        "@angular/cli": "1.0.0",
        "@angular/compiler-cli": "^2.4.6",
        "@types/jasmine": "2.5.43",
        "@types/node": "^7.0.5",
        "codelyzer": "~3.0.0-beta.3",
        "jasmine-core": "2.5.2",
        "jasmine-spec-reporter": "3.2.0",
        "karma": "1.5.0",
        "karma-chrome-launcher": "^2.0.0",
        "karma-phantomjs-launcher": "^1.0.4",
        "karma-cli": "^1.0.1",
        "karma-jasmine": "^1.0.2",
        "karma-remap-istanbul": "^0.6.0",
        "protractor": "~5.1.0",
        "ts-node": "2.1.0",
        "tslint": "^4.3.0",
        "typescript": "~2.2.1"
    }
SethDavenport commented 7 years ago

Huh - didn't test with angular2 (used angular 4 instead). Let me give that a try.

rpdasilva commented 7 years ago

webpack:///~/ng2-redux/lib/decorators/select.js:23:0 <- src/test.ts:140151:47

Is it possible this src/test.ts file is still trying to import from ng2-redux?

I would suggest blowing away your node_modules folder and doing a fresh npm install or yarn

SethDavenport commented 7 years ago

I was able to downgrade example-app to angular 2 and it still works for me. Did you give @rpdasilva's suggestion a try?