jasmine-react
v1.1.0
Published
Jasmine utilities and helpers for testing React components.
Downloads
44
Readme
jasmine_react
Turn a jasmine Suite into one suitable for testing React components.
Example:
var Checkbox = require('jsx!components/checkbox');
describe('Components.Checkbox', function() {
this.reactSuite({ type: Checkbox });
it('should render', function() {
expect(subject.isMounted()).toBeTruthy();
});
});
Features
The following features will become available to your suite:
Automatic component (un)mounting
In your global suite context, "subject" will contain a reference to the mounted instance of the component you're testing, created and mounted during each test in your suite.
DOM helpers
All the DOM helpers detailed below are injected into the global context throughout your tests, so you can conveniently use things like find()
and click()
.
Note
Most of these helpers operate on nodes inside the node of the component being tested, so when you do
find('.foo')
it will look for a child that has thefoo
class only inside the mounted component instance.
find(selector)
Locate a single element using a jQuery-compatible selector. Returns an HTMLElement
if found.
it('should show a link', function() {
expect(find('a:contains("My Link Text")').length).toBe(1);
});
findAll(selector)
Like find()
but returns a set of all elements that match the selector.
click(selector)
Simulate a mouse-click. If a selector was passed in and it did not yield an element, an error will be thrown.
it('should track clicks', function() {
click('button');
expect(subject.state.clickCount).toBe(1);
});
check(selector[, isChecked])
Toggle the checked
state of a radio button or a checkbox. You can explicitly set the state by passing true
or false
as the second parameter.
it('should track the mute-sound preference', function() {
check(':contains("Mute Sounds")', true);
expect(subject.state.muteSound).toBe(true);
});
select(selector, value)
Choose an option from a <select />
dropdown menu. The value parameter should map to the <option />
element you want to choose.
There is currently no support for multiple-option dropdowns.
it('should choose my primary currency', function() {
select('[name="currency"]', 'JOD');
expect(subject.state.currency).toEqual('JOD');
});
fillIn(selector, text)
Change a text-input field's value. This does not simulate typing, the typeIn
helper does that instead.
it('should track my favorite colour', function() {
fillIn('[name="colour"]', 'banana');
expect(subject.state.colour).toEqual('banana');
});
typeIn(selector, text[, dontReplace])
Simulate typing into a text field.
Typing in will change the node's value
, emit the change
event, along with a keydown
event for every character in the text.
it('should limit text to 10 chars', function() {
typeIn('input', 'hello you should not cut me off really its not nice');
expect(subject.state.text).toEqual('hello you');
});
Prop helpers
WARNING!!!
This requires jasmine.promiseSuite to be available from jasmine_rsvp.
setProps(newProps)
Update the component props. Returns an RSVP.Promise
that fulfills when the component has been re-rendered with the new props.
it('should render the name', function() {
expect(find('span.name').innerText).toEqual('');
setProps({
name: 'Ahmad'
});
expect(find('span.name').innerText).toEqual('Ahmad');
});
setState(newState)
Similar to #setProps()
but for the component's internal state, which generally you should avoid touching.
Custom matchers
toExist()
Shortcut for testing that a certain element exists in the DOM.
// Instead of:
expect(findAll('.something').length).toEqual(1)
// You can do:
expect('.something').toExist();
Action testing using toSendAction(nameOrOptions)
WARNING!!!
This requires jasmine.promiseSuite to be available from jasmine_rsvp.
This is very opinionated and most likely won't apply to your code, but it does to mine so it's here. My components are glued to only "emit" actions when there's any sort of processing required. This allows me to decouple the UI (components) from actual domain logic handling, and consequently, it makes testing component interaction pretty slick.
To test if a component is sending actions correctly, a custom matcher
is exposed to your suite, called toSendAction()
. The matcher accepts either a string, which would be the event such as user:signup
, or account:save
, or a more descriptive object (see below.)
Example:
it("should totally remove one's account when clicking the red button", function() {
expect(function() {
click('#the_red_button');
}).toSendAction('users:unregister');
});
Example 2: verifying the correct parameters are being sent.
We can also test the parameters the component is sending. Let's assume we have a Preferences
component that sends the updatePreferences
action
with the user's chosen preferences.
var Preferences = React.createClass({
render: function() {
return (
<form>
<select ref="weekday">
<option value="friday">Friday</option>
<option value="saturday">Saturday</option>
<option value="sunday">Sunday</option>
</select>
<button id="save">Save</button>
</form>
);
},
onClick: function() {
this.sendAction('updatePreferences', {
weekday: this.refs.weekday.value
});
}
});
If the user chooses Friday to be their starting day of the week, the component should emit the right action with that weekday:
it("set the prefered starting weekday", function() {
expect(function() {
select('[name="weekday"]', 'Friday');
click('#save');
}).toSendAction({
action: 'updatePreferences',
args: {
weekday: 'friday'
}
});
});
License
MIT