ngxs-labs / testing Goto Github PK
View Code? Open in Web Editor NEWMore power for testing with @ngxs-labs/testing
License: MIT License
More power for testing with @ngxs-labs/testing
License: MIT License
Hi, I'm creating unit tests and have a problem when testing actions. I would like to mock dispatch
function in a way it really dispatches only a tested action and any additional dispatch call are only spied.
Something like this:
it('should login with valid credentials', async (done) => {
const action = new Login(validCredentials)
const dispatchSpy = spyOn(store, 'dispatch').withArgs(action).and.callThrough()
store.dispatch(action)
await expect(store.selectSnapshot(AuthState.getError)).toBeFalsy()
await expect(store.selectSnapshot(AuthState.getPending)).toBeTruthy()
authTrigger.next()
const dispatchedLoginSuccessAction = [].concat(...dispatchSpy.calls.allArgs()).find(a => a instanceof LoginSuccess)
await expect(dispatchedLoginSuccessAction).toBeTruthy()
await expect(dispatchedLoginSuccessAction.payload).toEqual(token)
})
BUT! This doesn't work, because as I investigate, the store.dispatch
is different from the dispatch
function in the action context. I know I can use the construction like this without mocking (and it works):
actions$.pipe(ofActionDispatched(LoginSuccess)).subscribe(async (action) => {
await expect(action).toBeTruthy()
done()
})
BUT! I don't want to actually dispatch additional actions because of side effects. Consider the tested action dispatches an action from another module, so I would have to mock all services which causes side effects in that module.
I've found out the actual dispatch to be mocked is the one in the InternalStateOperations
object, but I don't know how to mock it.
QUESTION So what is the proper way to make tests like this?
I am having some issues with testing an Action which makes a API request and on success it dispatch an action which transform that response into a particular format .Is there any way to test API Action using Jest and check if the store is mutating based on API response.
Hi, thanks for this package. I am looking forward to use it but last time I checked ngxs website wasn't listed in there so I am not sure if it's ready to be used.
Also, it would be nice to know if I have other questions, where is the best way to ask them?
When I am unit testing my components that use a store, I often just want to mock the store to check whether the right dispatch methods were called.
However when the component contains @select you'll get a errors like:
Error: SelectFactory not connected to store!
Now we can use ugly hacks like the following to get rid of the errors:
Object.defineProperty(component, 'active$', { writable: true });
component.active$ = of([]);
But it would be nicer if we have the ability to have some helpers to mock the selects, or let the SelectFactory be mockable somehow.
See also: #482
I am using ngxs for state handling in angular, and I am trying to test our components as units, so preferably only with mock stores, states etc.
What we have in our component is something like:
export class SelectPlatformComponent {
@Select(PlatformListState) platformList$: Observable<PlatformListStateModel>;
constructor(private store: Store, private fb: FormBuilder) {
this.createForm();
this.selectPlatform();
}
createForm() {
this.selectPlatformForm = this.fb.group({
platform: null,
});
}
selectPlatform() {
const platformControl = this.selectPlatformForm.get('platform');
platformControl.valueChanges.forEach(
(value: Platform) => {
console.log("select platform " + value);
this.store.dispatch(new PlatformSelected(value));
}
);
}
}
And our fixture setup looks like this, so we can check calls on the store:
describe('SelectPlatformComponent', () => {
let component: SelectPlatformComponent;
let fixture: ComponentFixture<SelectPlatformComponent>;
let store: Store;
beforeEach(async(() => {
const storeSpy = jasmine.createSpyObj('Store', ['dispatch']);
TestBed.configureTestingModule({
imports: [ReactiveFormsModule],
declarations: [SelectPlatformComponent],
providers: [{provide: Store, useValue: storeSpy}]
})
.compileComponents();
store = TestBed.get(Store);
}));
But when we run this, we get the following error:
Error: SelectFactory not connected to store!
at SelectPlatformComponent.createSelect (webpack:///./node_modules/@ngxs/store/fesm5/ngxs-store.js?:1123:23)
at SelectPlatformComponent.get [as platformList$] (webpack:///./node_modules/@ngxs/store/fesm5/ngxs-store.js?:1150:89)
at Object.eval [as updateDirectives] (ng:///DynamicTestModule/SelectPlatformComponent.ngfactory.js:78:87)
at Object.debugUpdateDirectives [as updateDirectives] (webpack:///./node_modules/@angular/core/fesm5/core.js?:11028:21)
at checkAndUpdateView (webpack:///./node_modules/@angular/core/fesm5/core.js?:10425:14)
at callViewAction (webpack:///./node_modules/@angular/core/fesm5/core.js?:10666:21)
at execComponentViewsAction (webpack:///./node_modules/@angular/core/fesm5/core.js?:10608:13)
at checkAndUpdateView (webpack:///./node_modules/@angular/core/fesm5/core.js?:10431:5)
at callWithDebugContext (webpack:///./node_modules/@angular/core/fesm5/core.js?:11318:25)
at Object.debugCheckAndUpdateView [as checkAndUpdateView] (webpack:///./node_modules/@angular/core/fesm5/core.js?:10996:12)
I could enable the entire ngxs module for this, but then I would need to create services mocks to inject into state objects, which I do not like because I am then not testing the component in isolation anymore. I tried to create a mock SelectFactory, but it seems it is not exported from the module.
Is there a way to mock the SelectFactory, or inject some mocks into the platformList$ directly? Other suggestions?
PS: I also asked this on stackoverflow, but no real answer was given: https://stackoverflow.com/questions/51082002/how-to-mock-select-in-ngxs-when-using-a-mock-store
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.