-
-
Save iammerrick/49b4420d64f954fa6c5e to your computer and use it in GitHub Desktop.
import expect from 'expect'; | |
import AppConstants from '../../../app/AppConstants'; | |
import store from '../../store'; | |
import { selectLastReadMessageByChannelId } from './channelSelectors'; | |
describe('channel', () => { | |
it('should store the messageId when clearing unreads', () => { | |
const channelId = 1; | |
const messageId = 2; | |
store.dispatch({ | |
type: AppConstants.CHANNEL_UNREADS_CLEARED, | |
payload: { | |
id: channelId, | |
messageId | |
} | |
}); | |
expect(selectLastReadMessageByChannelId(store.getState(), channelId)).toEqual(messageId); | |
}); | |
}); |
@iammerrick: I say try it out and see if it works well - if it does, share it with the community!
It's similar to an approach I've tried to take in action creators that use getState
, using selectors to avoid something else dependent on the state tree
👍 to creating store
in a beforeEach
.
Alright thanks for feedback all, just wanted to make sure I wasn't doing anything crazy.
I have been using a similar approach for a while, except I utilize the action creators. My theory is that the isolation of tests as demonstrated in the docs does not give you must value in real applications. In real applications change is what introduces risk, atomic tests will not protect code well against change. You gain more value by testing that a given action creator results in an expected state. By explicitly passing action objects to a reducer you are testing the implementation, not the behavior.
This approach has already saved me several times as new requirements are introduced/discovered. Now when I change the implementation of an action, my asserts on state fail.
Here are two examples, one sync and one async.
https://gist.github.com/kloy/3d0dafe1f6974f88c909
https://gist.github.com/kloy/ef9e99ae67df24e68bdd
I still have not optimized my http mocking as I would prefer to work closer to angular's $http. As you can see I am utilizing a mock store. My mock store pulls in all of my reducers and all middleware that is not depending on globals/externals.
if you decided to change [x], you have to change [y]
Apps always change. For me, about the only thing I care about is that.
My favorite code allows me to change one thing w/o having to change many things.
For example, I don't assert an exact DOM structure for UI tests, I just assert that the user's name is displayed: I don't care if its in a <b/>
or <span/>
. You've got the same thing going on here by not coupling your tests to your state tree, you're testing "does this work" not "how does this work" and its 💯
(there are times I look at how simple my reducers--and everything else in a react redux app--are to think about and wonder why I'm even writing tests at all ...)
@iammerrick: Good point. This does seem to be a good lightweight approach to ensure the core functionality is working and still let you refactor easily.