-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
feat(store): use provideMockStore outside of the TestBed #2759
feat(store): use provideMockStore outside of the TestBed #2759
Conversation
Preview docs changes for 93d567a at https://previews.ngrx.io/pr2759-93d567a0/ |
42d8238
to
232ba9c
Compare
ce217ec
to
d63fc80
Compare
🤔 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like where this is going!
* }); | ||
* }); | ||
* ``` | ||
*/ | ||
export function provideMockStore<T = any>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about the following?
This is close to what you had, but I want to make sure that useExisting
is used, and it's a bit more compacted.
export function provideMockStore<T = any>( | |
export function provideMockStore<T = any>( | |
config: MockStoreConfig<T> = {} | |
): Provider[] { | |
setNgrxMockEnvironment(true); | |
return [ | |
{ provide: ActionsSubject, useFactory: () => new ActionsSubject(), deps: []}, | |
{ provide: MockState, useFactory: () => new MockState<T>(), deps: []}, | |
{ provide: MockReducerManager, useFactory: () => new MockReducerManager(), deps: []}, | |
{ provide: INITIAL_STATE, useValue: config.initialState || {} }, | |
{ provide: MOCK_SELECTORS, useValue: config.selectors }, | |
{ provide: StateObservable, useExisting: MockState }, | |
{ provide: ReducerManager, useExisting: MockReducerManager }, | |
{ | |
provide: MockStore, | |
useFactory: mockStoreFactory, | |
deps: [ | |
MockState, | |
ActionsSubject, | |
ReducerManager, | |
INITIAL_STATE, | |
MOCK_SELECTORS, | |
], | |
}, | |
{ provide: Store, useExisting: MockStore }, | |
]; | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alex-okrushko
Done. I assumed that StateObservable
needs useExisting: MockState
, but I added useFactory: () => new MockState()
in order to keep the same behavior as previous { provide: StateObservable, useClass: MockState }
.
About return type, I kept (ValueProvider | ExistingProvider | FactoryProvider)[]
, because if Provider[]
is used, following code will not compile:
injector = Injector.create({ providers: provideMockStore(...) });
because Provider
is not compatible with StaticProvider
and (ValueProvider | ExistingProvider | FactoryProvider)
is compatible with both Provider
and StaticProvider
.
mockSelectors | ||
); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of going through the Injector
every time, maybe let's create the getMockStore
or createMockStore
function:
export function getMockStore<T>( | |
config: MockStoreConfig<T> = {} | |
): MockStore<T> { | |
return Injector.create({ providers: [ provideMockStore(config) ]}).get(MockStore); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
d63fc80
to
ad4ae11
Compare
ad4ae11
to
93d567a
Compare
MockStore, | ||
{ | ||
provide: ActionsSubject, | ||
useFactory: () => new ActionsSubject(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use useClass
here?
useFactory: () => new ActionsSubject(), | |
useClass: ActionsSubject, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brandonroberts Because class providers are different for TestBed.configureTestingModule
and Injector.create
. TestBed.configureTestingModule
expects ClassProvider
. On the other hand, Injector.create
expects StaticClassProvider
. However, they both accept FactoryProvider
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, what about just { provide: ActionsSubject, deps: [] }
? I know it's compatible with the Injector, and should be compatible with the TestBed also
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason the ActionsSubject
is undefined
in this case.
useFactory: () => new ActionsSubject(), | ||
deps: [], | ||
}, | ||
{ provide: MockState, useFactory: () => new MockState<T>(), deps: [] }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here with useClass
{ provide: MockState, useFactory: () => new MockState<T>(), deps: [] }, | ||
{ | ||
provide: MockReducerManager, | ||
useFactory: () => new MockReducerManager(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same with useClass
This would be a separate effort, but what about creating a factory function for creating a https://github.com/brandonroberts/react-ngrx-poc/blob/master/src/store.tsx cc: @alex-okrushko |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot @markostanimirovic 👍
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
provideMockStore
can only be used withTestBed.configureTestingModule
.Closes #2745
What is the new behavior?
provideMockStore
can be used withTestBed.configureTestingModule
andInjector.create
.Does this PR introduce a breaking change?
Other information