Skip to content

Instantly share code, notes, and snippets.

@iammerrick
Created December 16, 2015 21:50
Show Gist options
  • Save iammerrick/49b4420d64f954fa6c5e to your computer and use it in GitHub Desktop.
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);
});
});
@trevordmiller
Copy link

@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.

@trevordmiller
Copy link

@iammerrick: I say try it out and see if it works well - if it does, share it with the community!

@statianzo
Copy link

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

@statianzo
Copy link

👍 to creating store in a beforeEach.

@iammerrick
Copy link
Author

Alright thanks for feedback all, just wanted to make sure I wasn't doing anything crazy.

@kloy
Copy link

kloy commented Dec 17, 2015

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.

@ryanflorence
Copy link

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 💯

@ryanflorence
Copy link

(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 ...)

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