I have been using Enzyme already for months for tests and none of the other tests fail, it is just with this element. I have made the code very barebone to see if I could figure out if I did something wrong but with this code it is still occuring:
The only change is replacing the original path with path/to of the import
See comments for the current outputs:
import React from "react";
import { expect } from "chai";
import enzyme from "enzyme";
import { BareHeader } from "path/to/bare_header.jsx";
describe("BareHeader", function(){
let component;
before(function(){
component = enzyme.shallow(<BareHeader currentStepNumber={1234}/>);
console.dir(component.props()); // {children: ..., className: "header-container"}
let compInst = component.instance();
console.dir(compInst.props); // {currentStepNumber: 1234}
});
//Fails: expected undefined to equal 1234
it("should have right prop", function(){
expect(component.prop("currentStepNumber")).to.equal(1234);
});
});
bare_header.jsx:
import React from "react";
class BareHeader extends React.Component {
render(){
return (
<div className="header-container">
<div className='header-hoverArea'>
<p>header placeholder</p>
</div>
</div>
);
}
}
export { BareHeader };
See comment for expected:
import React from "react";
import { expect } from "chai";
import enzyme from "enzyme";
import { BareHeader } from "path/to/bare_header.jsx";
describe("BareHeader", function(){
let component;
before(function(){
component = enzyme.shallow(<BareHeader currentStepNumber={1234}/>);
console.dir(component.props()); // {children: ..., currentStepNumber: 1234}
let compInst = component.instance();
console.dir(compInst.props); // {currentStepNumber: 1234}
});
//Passing
it("should have right prop", function(){
expect(component.prop("currentStepNumber")).to.equal(1234);
});
});
Mocha automated tests in MeteorJS application (1.6.1). Mocha distribution is meteortesting/meteor-mocha.
| library | version
| ---------------- | -------
| Enzyme | 3.3.0
| React | 16.2.0
| Meteor Mocha | 0.5.1
| Mocha | 2.4.5
same problem. I also got some tests failed after update enzyme to 3.3.0 and enzyme-adapter-react-16. previously it is pass:
expect(component.instance().props.title).toBe('Title 2');
now I have to make it to be like this to make it pass:
expect(component.props().children).toBe('Title 2');
I have to admit the issue started in 3.2.0 for me but stayed after updating to 3.3.0
Calling .props() on a shallow wrapper returns the props of the rendered element - not the props of the wrapper itself.
@bvanderdrift why are you writing a test that asserts on the prop value you literally just passed in a few lines prior?
I don't remember the actual code I had written for this. We currently don't have the test anymore. This example was very minimized, which is why it might look a bit weird, but could as well that I had written a very redundant test.
Thanks for the explanation, I guess the props different behaviour on instance and the object itself was confusing for me.
Thanks for replying - I'm going to close this for now, but will be happy to reopen if there's a reproducible case.
component.instance().props doesn't work no more with React 16 (functional components). Is there an alternative.
@himanshuc3 yes, component.props() - there's no reason to ever have accessed through the instance anyways.
I forgot to mention that i am using react-native. const wrapper = shallow(<Footer name="friend"/>)
console.log(wrapper.props().name) console log returns null.
@himanshuc3 although enzyme doesn't have a react-native adapter; that's because a shallow wrapper of <Footer> is not actually Footer, it's what Footer renders - there's zero value in making assertions on the props you literally just passed in.
So is there any way we could make assertions by passing props in react-native.
Tons - but there's no point in making assertions on the props you literally just passed in.
That is just a debugging statement. Actually i am conditional rendering and want to check on that by passing props. How would that be possible?
I'm not sure what you mean - can you elaborate?
i am also facing this updated issue, does someone fixed this?
@kevinlucero if you can provide a repro case, please file a new issue for that.
@ljharb im writing this code like function component with specific type :)
import React from 'react';
import Enzyme, { shallow, ShallowWrapper } from 'enzyme';
import { create, ReactTestRenderer } from 'react-test-renderer';
import sinon from 'sinon';
import Button, { ButtonKind, Props } from './index';
let wrapper: ShallowWrapper<Props>;
let snapshot: ReactTestRenderer;
let buttonFn: sinon.SinonSpy<any[], any>;
beforeEach(() => {
buttonFn = sinon.spy();
const button = <Button text="sample" kind={ButtonKind.Danger} />;
wrapper = shallow(button);
snapshot = create(button);
});
describe('<Button />', () => {
it('it should text must be sample', () => {
expect(wrapper.props().text).toEqual('sample');
});
it('it should kind must be ButtonKind.Danger', () => {
expect(wrapper.props().kind).toEqual(ButtonKind.Danger);
});
});
//wrapper.props() is null but I pass props if you can see in button declaration
//package.json
"jest": "^24.8.0",
"ts-jest": "^24.0.2"
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"enzyme-to-json": "^3.3.5",
@kevinlucero i specifically asked you to file a new issue - but the answer is the same. wrapper.props() for a shallow wrapper will NOT be the props you just passed (and thus have no need to assert on), but will be the props on the thing that Button renders.
Hey @kevinlucero
I was able to work around this using two stages in testing:
import React from 'react';
import { shallow } from 'enzyme';
import MyComponent from './MyComponent';
describe('MyComponent', () => {
it('should render MyComponent with an event handler', () => {
const spy = jest.fn();
let wrapper = shallow(<MyComponent />);
expect(wrapper).toMatchSnapshot();
wrapper = shallow(
<div>
<MyComponent onEvent={spy} />
</div>
);
wrapper
.childAt(0)
.props()
.onEvent();
expect(spy).toHaveBeenCalled();
});
})
@armin-th (btw that's really two tests, so it should be two its) I'm still confused what you're testing there. You literally are just testing that you passed spy to onEvent; you aren't testing a single thing about MyComponent - it's a useless test.
A dang, I meant to test that the event is handled by trigging something inside but wouldn't need to do any of what I wrote in the first place.
You'd do that by directly shallow-wrapping MyComponent, and not testing MyComponent's props directly (because you just passed them in; testing them is a waste of time)
I also had this problem, I was able to solve it when I used mount instead of shallow, and calling as follows .props().propName
it('should render a url property', () => {
const url = 'https://github.com'
const wrapper = mount(<GithubButton url={url} />)
expect(wrapper.props().url).toEqual(url)
})
Docs: https://enzymejs.github.io/enzyme/docs/api/ReactWrapper/props.html
Most helpful comment
component.instance().props doesn't work no more with React 16 (functional components). Is there an alternative.