Skip to content
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

Test passes even if not all expected actions are dispatched #12

Closed
dara76 opened this issue Jan 6, 2016 · 12 comments
Closed

Test passes even if not all expected actions are dispatched #12

dara76 opened this issue Jan 6, 2016 · 12 comments

Comments

@dara76
Copy link

dara76 commented Jan 6, 2016

I have the following set-up
actions.js

export function loadData() {
    return function (dispatch) {
        dispatch(transactions([876]));
    };
}

actions-test.js

  jest.dontMock('../actions');
  jest.dontMock('redux-mock-store');
  jest.dontMock('redux-thunk');

  const configureMockStore = require('redux-mock-store');
  const thunk = require('redux-thunk');
  const middlewares = [ thunk ];
  const mockStore = configureMockStore(middlewares);

describe('actions', () => {    
  it('should load data', (done) => {
    const expectedActions = [
      { type: actions.TRANSACTIONS, transactions : [876] },
      //{ type: actions.DOES_NOT_EXIST, foo : [] },
      //{ type: actions.EXISTS, foo : [] }
    ];

    const store = mockStore({}, expectedActions, done);
    store.dispatch(actions.loadData());
  });
});

Running the above test passes as expected.

The problem is if I uncomment

      //{ type: actions.DOES_NOT_EXIST, foo : [] },
      //{ type: actions.EXISTS, foo : [] }

the test still passes even though now only one of the 3 expectedActions is dispatched.

Is this a bug, or am I misunderstanding something?

@ngerritsen
Copy link

I have the same issue here, i did notice the examples were in mocha and I use jasmine, so that could be the problem maybe?

@kvnneff
Copy link

kvnneff commented Jan 8, 2016

The issue lies here, where expectedActions.length === 0 is being trusted to signal that all the expected actions have been dispatched.

For example, If you provide the mock store with a single expected action, and dispatch an async action creator that then dispatches multiple other actions, the done() callback will be called as soon as the first original action has been dispatched, without waiting for the subsequent actions to be dispatched.

I'm looking into ways to fix this.

@ryanirilli
Copy link

I also notice that this is using "expect": "^1.12.2" which uses deep-equal
https://www.npmjs.com/package/deep-equal

and in deep equal docs it states

If opts.strict is true, use strict equality (===) to compare leaf nodes. 
The default is to use coercive equality (==) 
because that's how assert.deepEqual() works by default.

but in the latest tag on the expect lib 1.13.4, it changed the dependency from deep-equal to using is-equal

https://www.npmjs.com/package/is-equal

but changing line 38 in redux-mock-store from
expect(action).toEqual(expectedAction); to expect(action).toEqual(expectedAction, {strict: true});
did not fix the problem.

Hope this helps, trying more things...

UPDATE - looks like you just need to updates expect to 1.13.4
mjackson/expect#53

verified upgrading to expect 1.13.4 works

@ngerritsen
Copy link

So redux mock store should be compatible with jasmine?

@kvnneff
Copy link

kvnneff commented Jan 9, 2016

There shouldn't be any difference between using mocha and jasmine, the bug exists no matter which test suite you use.

@ngerritsen
Copy link

For some reason switching to mocha fixes the issue for me.
This is what I have installed for both cases:

+-- redux-mock-store@0.0.6 
| `-- expect@1.13.4 
|   +-- is-equal@1.4.2 

this is the test:

import configureMockStore from 'redux-mock-store'
import thunk from 'redux-thunk'
import { pushState } from 'redux-router'

import { logout } from '../authentication'
import { LOGOUT } from '../../constants/action-types'

describe('authentication actions', () => {
  const middlewares = [ thunk ]
  const mockStore = configureMockStore(middlewares)


  it('logs out', done => {
    const expectedActions = [
      { type: LOGOUT },
      pushState(null, '/login')
    ]

    const store = mockStore({}, expectedActions, done)

    store.dispatch(logout())
  })
})

When using Jasmine I can just modify expectedActions and everyting still succeeds, with mocha I cannot:

// succeeds in Jasmine, fails with mocha
const expectedActions = [
    { type: 'does not exist' },
    pushState(null, '/login')
]

// or even:
const expectedActions = [
    { type: 'a' },
    { type: 'b' },
    { type: 'c' }
  ]

I don't know why or what I more information I can give you. I used "jasmine-core": "^2.3.4", and "mocha": "^2.3.4",

UPDATE
Same for "jasmine-core": "^2.4.1",

@frantic1048
Copy link

same issue explained by @ngerritsen.
I currently using such workaround to make it work on Jasmine (>_<)

import { createAction } from 'redux-actions';
import types from '../../lib/constants/ActionTypes';
// ...
const expectedActions = [
  act => expect(act).toEqual(createAction(types.FETCH_POSTS_REQUEST)()),
  act => expect(act).toEqual(createAction(types.FETCH_POSTS_SUCCESS)(posts)),
];

@jingzhou123
Copy link

+1.

@jingzhou123
Copy link

according to jasmine documentation, The done.fail function fails the spec and indicates that it has completed., but redux-mock-store call done(exception). Is this the problem?

@nikolasleblanc
Copy link

Yes I believe that's the issue.

@nikolasleblanc
Copy link

In the meantime, here's a temporary module for Jasmine (and Mocha): https://www.npmjs.com/package/redux-mock-store-jasmine

@arnaudbenard
Copy link
Contributor

There's a new version out, please give it a try 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants