pzavolinsky / react-unit Goto Github PK
View Code? Open in Web Editor NEWLightweight unit test library for ReactJS
License: MIT License
Lightweight unit test library for ReactJS
License: MIT License
Hi ,
I am new to React testing and I am trying to figure out how to injectIntl into my testing component.
For example: MyComponent exports like below
export default withStyles(styles)(injectIntl(SecurityQuestions));
But when I do tests
var component = createComponent();
it's throwing an error that intl is not found in its ancestry.
Even if I try to wrap around with it does not work.
React's shallowRenderer.render
takes an optional 2nd parameter, context
. It would be nice to be able to pass this context in as the 2nd parameter to createComponent
.
I have tried to get this working, but my functional programming knowledge isn't nearly good enough to understand how this library works. I was hoping it might be trivial for you to accomplish, although I will keep working on it in the mean time.
I'm using findByQuery
to target a span, which contains a child button element. Then I try to assert on the text of the span, but it comes back as an empty string with the text of the button omitted.
Is this expected behaviour? It seems a bit strange to me.
I've written a snippet of code which replicates what I'm talking about:
import React from 'react'
import createComponent from 'react-unit'
import {expect} from 'chai'
class TestComponent extends React.Component {
render() {
return (
<span>
<button>Hello World</button>
</span>
)
}
}
describe('Component', () => {
it('should be able to assert text in child element', () => {
const component = createComponent.shallow(<TestComponent />);
const buttonWrapper = component.findByQuery('span')[0];
const button = component.findByQuery('button')[0];
expect(button.text).to.eq('Hello World');
expect(buttonWrapper.text).to.eq('Hello World');
});
});
Here's the output when run, line 22 being the second expect:
If your React components are ES6 classes and contain child components, the shallow and interleaved rendering do not work.
The reason is that the components do not end up with a .displayName
property. As such, the output of component.dump()
ends up looking like:
<div>
<undefined/>
</div>
The fix is to fallback to ctor.type.name
(the name of the ES6 class function):
type: ctor.type.displayName || ctor.type.name
import React from 'react';
import Hello from './Child';
export default class Parent extends React.Component {
render() {
return <div><Child/></div>
}
}
import React from 'react';
export default class Child extends React.Component {
render() {
return <div>Hello World</div>
}
}
I think it would be ideal to do something like this:
the component:
export class AClass extend React.Component {
hiMom() {
console.log('Hi Mom!');
}
render() {
return (<div />);
}
}
the speudo "test":
let component = createComponent(<AClass />);
component.hiMom();
If there is a desire more than just from me, I may open a pr.
This line is breaking tests using jsdom. Looks to be changing global document. Commenting it out fixes the tests but unsure if it breaks anything within this module
If I do this:
class Original {
render() {
return (<span>I'm the original</span>);
}
}
class Parent {
render() {
return (<Original>{ this.props.children }</Original>);
}
}
class Mock {
render() {
return (<span>I'm the mock</span>);
}
}
var component = createComponent
.mock(Original, Mock)
(Parent);
console.log(
component.findByComponent(Mock).length,
component.findByComponent(Original).length
);
I get: "0 1"
When I would think that the result should be: "1 0"
Here's my test...
import React from 'react/lib/ReactWithAddons';
import createComponent from 'react-unit';
import tape from 'tape';
import addAssertions from 'extend-tape';
import jsxEquals from 'tape-jsx-equals';
// Component to test
import Toggle from '../../../../lib/app/components/Toggle/Toggle';
const TestUtils = React.addons.TestUtils;
const test = addAssertions(tape, {jsxEquals});
test('Component::Toggle', (t) => {
function toggleSidebar(value) {
return {
type: 'TOGGLE_SIDEBAR',
value
};
}
// Shallow rendering: Render React element only *one* level deep
const component = createComponent.shallow(<Toggle layout={{sidebarOpen: true}} actions={{toggleSidebar: toggleSidebar}} />);
// Test component props and content
t.equal(component.props.className, 'toggle-burger toggle-burger-x is-active', 'sidebarOpen prop should set an active class on the component');
t.end();
});
If my react component imports a SCSS file, the tests fail to run.
/**
* External dependencies
*/
import React, { Component, PropTypes } from 'react';
import classNames from 'classnames';
import './Toggle.scss';
class Toggle extends Component {
constructor() {
super();
this._handleToggle = this._handleToggle.bind(this);
}
Hi there,
There seems to be an issues whereby when you instantiate a react component via proxiquireify and perform a findByComponent on a subcomponent that react-unit us unable to find it even when a .dump() returns the item to be found.
e.g. If was was proxyquiring a Header component and within it, there was a Logo component.
Without proxying it, the findByComponent will return the Logo component but as soon as you proxyquirify the
Reference proxiquirify
hey, this seems like a really awesome module and keen to use it in a React project, thanks! ๐
this isn't hugely important, i'm mostly just curious: would it be possible to use min-document
as the minimal DOM implementation? that way this module can focus on the core features of unit testing with React instead of having to roll its own minimal DOM (and all the nuances of that endeavour).
When components are created, the property text
is set to the concatenation of its texts.
It works in most cases. However it adds some extra spaces as the code joins texts together by adding spaces.
It makes tests difficult to write.
For instance, consider this simple react component that displays a time period:
const DateRange = ({from, to}) => {
return <div>{from} - {to}</div>
}
When testing with the following code:
var component = createComponent(<DateRange from="Mon" to="Tue"/>);
expect(component.findByQuery('div')[0].text).to.equal('Mon - Tue');
The code fails with the following:
AssertionError: expected 'Mon - Tue' to equal 'Mon - Tue'
+ expected - actual
-Mon - Tue
+Mon - Tue
Can I use this in mocha without any jsdom / phantomjs? The code seems to suggest shallow rendering is used internally, but the sizzle lib requires a dom.
Once the React 0.14 is released, we can completely remove the global document
and don't pollute global scope at all.
From facebook/fbjs#59
We'll push out a new fbjs version from here soon and then update the React dependency. 0.14 should be going out soon and I'll make sure it includes this.
Issue just as a reminder.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.