Object property order and deep equals: expected behavior?
See original GitHub issueFantastic library. Thank you!!!
I have a question about object comparison. I’m using @ngrx/effects
in an Angular project. I’m using Jest as my testing framework. I have a class called UserEffects
that listens for login attempts and deals with the side effects:
@Injectable()
export class UserEffects {
// Listen for and handle login events
@Effect() login$: Observable<Action> = this.action$.pipe(
ofType('[User] Start Login'),
mergeMap(() => this.auth.login().pipe(
map((res: AuthResult) => ({ type: '[User] Successful Login', payload: res })),
catchError(() => of({ type: '[User] Failed Login' }))
))
);
constructor(private action$: Actions, private auth: AuthService) {}
}
I’ve also got a bunch of helper classes that inherit from Action
that can be used to generate actions, e.g.
export class LoginSuccess implements Action {
readonly type = UserActionTypes.LoginSuccess;
constructor(public payload: AuthResult) {}
}
My DESIRED test looks like this:
it("should catch login attempts", marbles((m) => {
const authRes = { accessToken: '12345', idToken: '67890', refreshToken: 'abcde' } as AuthResult;
const loginStart = new UserActions.LoginStart();
const loginSuccess = new UserActions.LoginSuccess(authRes); // <-- THIS DOES NOT WORK
action$ = m.cold("a---", { a: loginStart } );
const response = m.cold("--r-", { r: authRes } );
const expected = m.cold("--b-", { b: loginSuccess } );
auth.login = jest.fn(() => response);
m.expect(fx.login$).toBeObservable(expected);
}));
However, when I run this test, I get output that looks like this:
Expected
{"frame":20,"notification":{"kind":"N","value":{"type":"[User] Successful Login","payload":{"accessToken":"12345","idToken":"67890","refreshToken":"abcde"}},"hasValue":true}}
to deep equal
{"frame":20,"notification":{"kind":"N","value":{"payload":{"accessToken":"12345","idToken":"67890","refreshToken":"abcde"},"type":"[User] Successful Login"},"hasValue":true}}
If you look at these closely, you can see that the ONLY difference between the actual and expected values is the order of the properties. If I re-write my test like this…
it("should catch login attempts", marbles((m) => {
const authRes = { accessToken: '12345', idToken: '67890', refreshToken: 'abcde' } as AuthResult;
const loginStart = new UserActions.LoginStart();
const loginSuccess = { type: '[User] Successful Login', payload: authRes }; // <-- THIS WORKS!!
action$ = m.cold("a---", { a: loginStart } );
const response = m.cold("--r-", { r: authRes } );
const expected = m.cold("--b-", { b: loginSuccess } );
auth.login = jest.fn(() => response);
m.expect(fx.login$).toBeObservable(expected);
}));
…my tests pass.
Is there any way to specify a different function for performing object comparison? I expect that there’s some way I could use configure()
or marbles()
to specify this, but I couldn’t quite figure it out.
Issue Analytics
- State:
- Created 6 years ago
- Comments:5 (3 by maintainers)
If you are using Jest, you might want to try it with Jest’s matchers. See this issue: https://github.com/cartant/rxjs-marbles/issues/13.
Glad it’s solved.
However, I don’t know what could have been happening, as I’ve added a test that uses class instances - https://github.com/cartant/rxjs-marbles/commit/3a3cb4074df05d675d510ff18caa670861b612e8 - and it’s fine.
Anyway, the Jest matchers effect much nicer output.