Mocking a function with Sinon - unit-testing

I cant seem to find a way to do a really simple thing like the below:
render() {
return (
<div className="messageDetail">
<div className="messageForm" >
Name: <input id="senderMsgName" value={this.props.nameValue} onChange={this.props.handleNameChange}/>
<br />
Body: <input id="senderMsgBody" value={this.props.bodyValue} onChange={this.props.handleBodyChange}/>
<br />
</div>
</div>
);
}
}
All I want to test is that the onChange function is called. how can I mock this out using sinon (bearing in mind it called on props)? I then will simulate it being called to test it.
I started with this: const handleBodyChangeSpy = sinon.spy();
and will expect this: expect(handleBodyChangeSpy).to.have.not.been.called();
just need some guidance on how to do that

I assume you are using ES6 and class Component extends React.Component. In that case you can create a spy by writing var spy = sinon.spy(Component.prototype, "handleBodyChange"). You can test your assertions on that spy.
More about creating spies here: http://sinonjs.org/releases/v1.17.7/spies/ (check under Creating spies: sinon.spy() Method Signatures).

Related

Trouble unit testing onClick method using Mocha Chai and Enzyme

I'm having trouble with unit testing using mocha, chai and enzyme for the following. I can't seem to understand how to unit test methods in components and how to unit test onClick methods will call those methods.
The following is what I am trying to unit test:
<Link to="/create-new-template-results" onClick={this.checkLink}>
<Button
buttonname="Next_button"
variant="primary"
label="Save"
onClickMethod={() => this.submitTemplateCreation()}
disabled={!this.disabledButtonCheck()}
/>
</Link>
.
Header: '',
Cell: value => {
return (
<div>
<img
height={34}
src="https://content.usaa.com/mcontent/static_assets/Media/icon-trash.svg"
onClick={() => this.removeAttribute(value)}
/>
</div>
);
}
.
removeAttribute = value => {
this.props.change('templateAttributeForm', value.original.name, '');
this.props.removeAttributeItem(value.index);
};
submitTemplateCreation() {
let profLvlData = Object.values(this.props.templateAttributeFormData);
let attrData = Object.keys(this.props.templateAttributeFormData);
let attributeProfLvl = attributeProfLvlUtil(attrData, profLvlData);
let templateCreationJSON = templateCreationPOSTFilter(attributeProfLvl, this.props.templateFormData);
this.props.submitTemplateCreation(templateCreationJSON);
}
Chai provides some nice tools for testing things exactly like what you are talking about.
You'll want to render your component somehow in the virtual DOM, either by using enzyme's "shallow" or "mount" functions.
Once you've done that, you can access the component using .find, and "simulate" an event using .simulate like so.
wrapper.find('Button').at(0).simulate('click');
This will find all of the 'Button' components in your wrapper, take the first one, and simulate a click. From there you can use expect() combined with any of the ways Chai provides to examine the state of the component in order to test that your button did what it was supposed to.
Since it seems like you are particularly interesting in the calling of the onClick function itself, I will add that you can specifically check to see if a function is called by doing the following with Chai.
expect(MyComponent.prototype.myOnClickFunction).to.have.property('callCount', 1);

Using Jest to mock a component which has other components as properties

I'm trying to mock react-bootstrap <Modal> component with jest. <Modal> contains some "sub-components" as properties, for example <Modal.Header>. I'm trying to find out the correct way to mock this kind of components using Jest.
Here's a simple component using <Modal>:
// mymodal.js
import React from 'react'
import {Modal, Button} from 'react-bootstrap'
const MyModal = ({ visible, hide, title, onOk }) =>
<Modal show={visible} onHide={hide}>
<div className='simple-modal'>
<Modal.Header closeButton>{title}</Modal.Header>
<Modal.Body>
<div>I'm body</div>
</Modal.Body>
<Modal.Footer>
<Button className='invert-primary' onClick={hide}>
Cancel
</Button>
<Button bsStyle='primary' onClick={onOk}>
Ok
</Button>
</Modal.Footer>
</div>
</Modal>
export default MyModal
And here's basic snapshot test for it:
// mymodal.test.js
import renderer from 'react-test-renderer'
import * as React from 'react'
import MyModal from './mymodal'
jest.mock('react-bootstrap', () => {
function Modal(props) {
return <div>{props.children}</div>
}
Modal.Header = 'Modal.Header'
Modal.Body = 'Modal.Body'
Modal.Footer = 'Modal.Footer'
return({
Modal: Modal,
Button: 'Button',
})
})
describe('MyModal component', () => {
test('should render a modal', () => {
const modal = renderer.create(<MyModal
visible={true}
hide={() => ''}
onOk={() => ''}
title='Title' />)
expect(modal.toJSON()).toMatchSnapshot()
})
})
And here's snapshot:
// Jest Snapshot v1
exports[`MyModal component should render a modal 1`] = `
<div>
<div
className="simple-modal"
>
<Modal.Header
closeButton={true}
>
Title
</Modal.Header>
<Modal.Body>
<div>
I'm body
</div>
</Modal.Body>
<Modal.Footer>
<Button
className="invert-primary"
onClick={[Function]}
>
Cancel
</Button>
<Button
bsStyle="primary"
onClick={[Function]}
>
Ok
</Button>
</Modal.Footer>
</div>
</div>
`;
I'm quite happy with the snapshot result, but I'd like to get better output for the <Modal> component itself so that the snapshot would contain also component's name (currenlty <div>) and props (currently no props shown).
How should the mocking be done to achieve this?
I couldn't find way to achieve this with jest mocking. Finally I went with enzyme shallow rendering, which handles the basic mocking out of box. To do spanshot matching, I serialized the enzyme wrappers using enzyme-to-json npm package.

How do i unit test a react app that has all the text fields in the children components?

I have created a react application that has all the logic (like onchange functions) in the parent and all the html rendering in the children components.
In order to test if the right state changes are happening i have to enter text to the input fields and enter values but the only problem is I dont know how to access the children elements when i mount the parent in js dom.
Should i move logic into the child components or should i only unit test the functions of the parent component?
This is from the parent
render() {
if (!this.state.accessTokenEntered) {
return <AccessTokenPage _onChange={this._onChange}
accessToken={this.state.inputs.accessToken}
env={this.state.inputs.env}
_onFirstClick={this._onFirstClick}/>;
and this is the child
const AccessToken = props =>(
<Layout>
<Input name={"accessToken"} displayName={"Access Token"} _onChange={props._onChange}
value={props.accessToken}/>
<DropDown name={"env"} displayName={"Environment"} _onChange={props._onChange}
data={['ppe', 'prod']} multiple={false}
value={props.env}/>
<br/>
<div style={{"textAlign": "center"}}>
<input type="button" onClick={props._onFirstClick} className="btn btn-primary" value="Submit"/>
</div>
</Layout>
);
and this is the childs child
const Input = props => (
<div className="form-group row">
<label className="col-xs-2 col-form-label">{props.displayName}</label>
<div className="col-xs-10">
<input name={props.name} className="form-control" value={props.value}
onChange={props._onChange}/></div>
</div>
);
You should be testing your child component. When the onChange event of the textbox is simulated, test if the onChange prop is called. This can be done by creating a mock or spy for the onChange prop.
An example test is shown below:
Mocking a prop.
beforeEach(() => {
onAdd = jest.fn();
add = TestUtils.renderIntoDocument(<Add onAdd={onAdd} />);
});
Test if the mock method is called:
it('Button click calls onAdd', () => {
const button = TestUtils.findRenderedDOMComponentWithTag(add, 'button');
const input = TestUtils.findRenderedDOMComponentWithTag(add, 'input');
input.value = 'Name 4';
TestUtils.Simulate.change(input);
TestUtils.Simulate.click(button);
expect(onAdd).toBeCalledWith(input.value);
});
I am using Jest and React TestUtils. Similar code is available for enzyme in my github project.

Polymer. How to unit test filter function

I'm using Polymer. I have simple filter function:
_queryFilter: function(query){
return function(field){
if (!query) return true;
if (!field) return false;
return (field.name && ~field.name.indexOf(query));
};
}
This is element:
<input type="text" placeholder="filter" value="{{filterVal::input}}">
<template is="dom-repeat" items="{{fields}}" filter="{{_queryFilter(filterVal)}}">
{{item.name}}
</template>
I want to unit test it this way: give fixtured 'fields' array, give 'query' and check the output which function will give. How to do this ?
Web Component Tester (WCT) is used for testing Polymer elements. To test your template repeater's filter function, there are two relevant points from the Polymer Testing Guide:
https://www.polymer-project.org/1.0/tools/tests.html#test-fixtures
To use a test fixture:
Define the test fixture template and give it an ID.
Define a variable in your test script to reference the template.
Instantiate a new instance of the fixture in your setup() method.
https://www.polymer-project.org/1.0/tools/tests.html#test-dom-mutations
Always wrap your test in flush if your element template contains a template repeater (dom-repeat) or conditional template (dom-if), or if your test involves a local DOM mutation. Polymer lazily performs these operations in some cases for performance. flush ensures that asynchronous changes have taken place. The test function should take one argument, done, to indicate that it is asynchronous, and it should call done() at the end of flush.
Given:
<dom-module id="x-foo">
<template>
<input type="text" placeholder="filter" value="{{filterVal::input}}">
<ul>
<template is="dom-repeat" items="{{fields}}" filter="{{_queryFilter(filterVal)}}">
<li class="name">{{item.name}}</li>
</template>
</ul>
</template>
<script>...</script>
</dom-module>
Your test.html would look something like this:
<test-fixture id="basic">
<template>
<x-foo></x-foo>
</template>
</test-fixture>
<script>
suite('<x-foo>', function() {
var list, listItems;
setup(function() {
list = fixture('basic');
});
test('filters fields', function(done) {
list.fields = [
{name: 'foo'},
{name: 'bar'}
];
list.filterVal = 'f';
flush(function() {
listItems = Polymer.dom(list.root).querySelectorAll('li.name');
assert.equal(1, listItems.length);
assert.equal('foo', listItems[0].textContent);
done();
});
});
});
</script>
Your unit test for _queryFilter() could look like this:
test('_queryFilter() performs filtering', function() {
var filter = list._queryFilter('o');
var passedFilter = function(field) {
return filter(field) !== 0;
};
assert.isTrue(passedFilter({name: 'foo'}));
assert.isFalse(passedFilter({name: 'bar'}));
});
I recommend playing around with Polymer Starter Kit, which already includes a couple test elements scaffolded with WCT (e.g., app/test/my-list-basic.html).

How can I access inline style using React findDomNode function?

I am currently Jest to test React component, component's inline style would be changed according to different props value.
this is an example about what I wanna do:
let firstChild = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, 'div');
expect(firstChild.getDOMNode().style).toEqual({
fontSize: '20px'
});
This is the component props:
let renderedComponent = TestUtils.renderIntoDocument(
<CircleIcon
size="small" />
And this is the component dom to test with:
return (
<div className="circle-icon" style={boxStyle}>
<span className={this.props.icon}></span>
</div>
);
If I can get what is inside boxStyle, I can assert the test result from it.
Thanks a lot!
actually it works.
usage:
firstChild.getDOMNode().style.backgroundColor