-
-
Save ThomasBurleson/d2d62c8086e562621e597ba330aa38d6 to your computer and use it in GitHub Desktop.
import { NgModule } from '@angular/core'; | |
import { TestBed } from '@angular/core/testing'; | |
import { readFirst } from '@nrwl/nx/testing'; | |
import { EffectsModule } from '@ngrx/effects'; | |
import { StoreModule, Store } from '@ngrx/store'; | |
import { NxModule } from '@nrwl/nx'; | |
/** | |
* NgRx feature slice for 'Cars' state | |
*/ | |
import { LoadCars, CarsLoaded } from './cars.actions'; | |
import { CarsEffects } from './cars.effects'; | |
import { CarsFacade } from './cars.facade'; | |
import { CarsState, Entity, initialState, carsReducer } from './cars.reducer'; | |
/** | |
* The full-app NgRx state only has a 'cars' feature slice | |
*/ | |
interface TestSchema { | |
'cars' : CarsState | |
} | |
describe('CarsFacade', () => { | |
let facade: CarsFacade; | |
let store: Store<TestSchema>; | |
let createCars; | |
beforeEach(() => { | |
createCars = ( id:string, name = '' ): Entity => ({ | |
id, | |
name: name ? `name-${id}` : id | |
}); | |
}); | |
describe('used in NgModule', async (done) => { | |
beforeEach(() => { | |
@NgModule({ | |
imports: [ | |
StoreModule.forFeature('cars', carsReducer, { initialState }), | |
EffectsModule.forFeature([CarsEffects]) | |
], | |
providers: [CarsFacade] | |
}) | |
class CustomFeatureModule {} | |
@NgModule({ | |
imports: [ | |
NxModule.forRoot(), | |
StoreModule.forRoot({}), | |
EffectsModule.forRoot([]), | |
CustomFeatureModule, | |
] | |
}) | |
class RootModule {} | |
TestBed.configureTestingModule({ imports: [RootModule] }); | |
store = TestBed.get(Store); | |
facade = TestBed.get(CarsFacade); | |
}); | |
/** | |
* The initially generated facade::loadAll() returns empty array | |
*/ | |
it('loadAll() should return empty list with loaded == true', async (done) => { | |
try { | |
let list = await readFirst(facade.allCars$); | |
let isLoaded = await readFirst(facade.loaded$); | |
expect(list.length).toBe(0); // initially empty | |
expect(isLoaded).toBe(false); // initially not loaded | |
facade.loadAll(); // In our case loadAll() always returns an empty array. | |
list = await readFirst(facade.allCars$); | |
isLoaded = await readFirst(facade.loaded$); | |
expect(isLoaded).toBe(true); // data load completed | |
expect(list.length).toBe(0); | |
done(); | |
} catch (err) { | |
done.fail(err); | |
} | |
}); | |
/** | |
* Use `CarsLoaded` to manually submit list for state management and | |
* test that our observable is properly streaming data changes. | |
*/ | |
it('allCars$ should return the current list', async (done) => { | |
try { | |
let list = await readFirst(facade.allCars$); | |
let isLoaded = await readFirst(facade.loaded$); | |
expect(list.length).toBe(0); | |
expect(isLoaded).toBe(false); | |
// Here we are testing our NgRx actions, reducers, and selectors. | |
// Simulate results of a loadAll() and add two (2) cars to our NgRx 'cars' state. | |
store.dispatch(new CarsLoaded([ | |
createCars('AAA'), | |
createCars('BBB') | |
])); | |
list = await readFirst(facade.allCars$); | |
isLoaded = await readFirst(facade.loaded$); | |
expect(list.length).toBe(2); | |
expect(isLoaded).toBe(true); | |
done(); | |
} catch (err) { | |
done.fail(err); | |
} | |
}); | |
}); | |
}); |
Hey Thomas,
I have a quick question, as I am updating my application to now use Angular Ivy. I am running in to an issue where
all my test are failing because of an import incompatibility for the "readFirst" (operator) import { readFirst } from '@nrwl/nx/testing';
I changed it to import { readFirst } from '@nrwl/angular/testing'; that breaks my testing with a conflicting between 'rxjs/internal/Observable'.Thank you for your time, I hope my explanation was clear enough.
Having the same issue:
TS2345: Argument of type 'import("/Users/..../node_modules/rxjs/internal/Observable").Observable<import("/Users/.../libs/bundles/src/lib/+state/bundles.reducer").Entity[]>' is not assignable to parameter of type 'import("/Users/..../node_modules/@nrwl/angular/node_modules/rxjs/internal/Observable").Observable<import("/Users/..../libs/bundles/src/lib/+state/bundles.reducer").Entity[]>'. The types of 'source.operator.call' are incompatible between these types. Type '(subscriber: import("/Users/.../node_modules/rxjs/internal/Subscriber").Subscriber<any>, source: any) => import("/Users/.../node_modules/rxjs/internal/types").TeardownLogic' is not assignable to type '(subscriber: import("/Users/.../node_modules/@nrwl/angular/node_modules/rxjs/internal/Subscriber").Subscriber<any>, source: any) => import("/Users/.../node_modules/@nrwl/angular/node_modules/rxjs/internal/types").TeardownLogic'. Types of parameters 'subscriber' and 'subscriber' are incompatible. Type 'import("/Users/.../node_modules/@nrwl/angular/node_modules/rxjs/internal/Subscriber").Subscriber<any>' is not assignable to type 'import("/Users/.../node_modules/rxjs/internal/Subscriber").Subscriber<any>'. Property 'isStopped' is protected but type 'Subscriber<T>' is not a class derived from 'Subscriber<T>'.
My solution was to make sure that both the application's rxjs and nrwl's rxjs were the same version. I adjusted the version in app's package.json to be the same as with the nrwl's one. Actually it was only a minor-level change, from 6.5.4 to 6.5.3.
Hey Thomas,
I have a quick question, as I am updating my application to now use Angular Ivy. I am running in to an issue where
all my test are failing because of an import incompatibility for the "readFirst" (operator) import { readFirst } from '@nrwl/nx/testing';
I changed it to import { readFirst } from '@nrwl/angular/testing'; that breaks my testing with a conflicting between 'rxjs/internal/Observable'.
Thank you for your time, I hope my explanation was clear enough.