I have a component named AddEditVehicle which renders when the route is /vehicle/:vehicleId/edit.
I need to test the React lifecycles of this component. So I have used Enzyme mount to render my component in the unit test in the following way.
beforeEach(async () => {
wrapper = await mount(
<BrowserRouter>
<Provider store={store}>
<AddEditVehicle match={{ params: { vehicleId } }} />
</Provider>
</BrowserRouter>
);
await wrapper.update();
});
this wrapper fails to pass the required params making following specs to fail.
it("expect `isEditMode` value to set", () => {
const componentState = wrapper.find("AddEditVehicle").instance().state;
expect(componentState.isEditMode).toEqual(true);
});
Versions :
react ^16.4.2
react-router ^4.3.1
jest ^23.5.0
enzyme ^3.4.4
The problem with my approach was my Component was part of a Route but still, I was wrapping the component with withRouter which is redundant. So, in the unit test when I was passing the Route match details it was getting overridded. Thus, removing the withRouter made the solution work.
Related
I am unit testing my React app with jest and enzyme and all is good until I happened to test a class component connected with Redux. I went ahead and tested it by wrapping the component with a and then shallow mounting it. However I am not able to run assertions after updating the props of component, nor I am able to spy on the class methods being called or not.
Below is my sample code:
const wrapper = shallow(
<Provider store={store}>
<TestComponent {...props} />
</Provider>
).dive();
Now when I try t set the props of the wrapper and run assertions, it fails:
wrapper.setProps({
showHeader: true
})
expect(wrapper.find('h1')).toHaveLength(1);
Interesting part is, if I export the unconnected component as also suggested in redux docs, the assertions work well. Is it fine to export the unconnected component just for the purpose of testing? I can't spy on instance methods/lifecycle methods if I try to test the connected component.
You can mock the connect function from react-redux to return the original component
jest.mock('react-redux', () => ({
connect: () => Component => Component
}))
I'm trying to test my App component which is nested inside withRouter
export default withRouter(App);
In my index.js
ReactDOM.render(
<BrowserRouter>
<App client={client}/>
</BrowserRouter>,
document.getElementById('root')
);
My Test
describe("Test: Home page", ()=>{
const client = {}
let w = shallow(<App client={client}/>)
it("Always render the header", ()=>{
expect(w.find('header').length).toBe(1)
});
});
except the header isn't found and it returns 0 instead of 1
I've looked online but the only other example is grabbing a snapshot whereas I'm trying to check for rendered components
I'm not really sure, but since you are exporting App with a router, the shallow rendering will only render the router component and not the App component itself. You could try to use the wrappedcomponent property of the router to shallow render the component itself and not the router.
source and example
If you are using enzyme use mount instead of shallow.
shallow as name suggest render shallow, which means does not render children, where as mount will completely render with children and your header will be present.
I have a code in redux which i exported as
export default connect(mapStateToLinkProps, mapDispatchToLinkProps)(Link);
And in jest test case i have written to test this exported component
//imported the above component as Link
describe('Dashboard component testing', () => {
test('1. Must be an Instance of CreateAssest', () => {
const wrapper = shallow(<FilterLink />);
const inst = wrapper.instance();
expect(inst).toBeInstanceOf(Link);
});
});
For this i'm getting error
Invariant Violation: Could not find "store" in either the context or
props of "Connect(Link)". Either wrap the root component in a
, or explicitly pass "store" as a prop to "Connect(Link)".
When not using redux and exporting only as react component the test cases were working.Now in redux some store issue is coming.please can anyone guide a little in this issue what's happening
You need to wrap your component in Provider in order to be able to use store, like so:
import { Provider, connect } from "react-redux";
let store = createStore(reducer, defaultStoreItems);
<Provider store={store}>
<App />
</Provider>
I'm using react native 0.40 with jest 20. When trying to test the inner method of a component I fail because I cannot get the instance of it and then call the method.
For example I can test the rendered component using the snapshots like
it('renders correctly', () => {
var store = mockStore(initialState);
const tree = renderer.create(
<Provider store={store}>
<App/>
</Provider>
).toJSON()
expect(tree).toMatchSnapshot()
})
But if I try to test an inner method of the App component I don't find any way to access it.
So the following code will not run
it("checks version number correctly", () => {
var store = mockStore(initialState);
const tree = renderer.create(
<Provider store={store}>
<App/>
</Provider>
)
expect(tree.needsUpdate("1.0.0")).toBe(true)
})
The solution some people used was "react-test-renderer/shallow" or "enzyme" to shallow render the component and access the inner method, but the first one cannot be found when I import it (maybe related to RN version?) and enzyme cannot be installed properly (maybe again, a dependency issue). So what I wonder is, what's the best way to test an inner method.
You don't have to actually wrap your component in a provider. If you just want to test your component, you can export it without connect()(). For instance:
export class App extends React.Component {
// your things
}
export default connect()(App);
Inside your test file, you can import your app like so:
import ConnectedApp, { App } from "../App";
Then when you want to test your encapsulated App, you can treat it like any other standard component:
const props = {
// mocked-out props your store would provide
};
const component = shallow(<App {...props} />);
component.instance().whateverMethodYouWant();
Personally, I never wrap a component in a mock provider unless I need to render and deeper components are connected.
I am trying to practice using Redux/testing React, and have a simple app set up with the Facebook Create-React Kit.
I have a basic test that is just supposed to make sure an element renders:
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render( < Companies / > , div);
});
It was passing until I implemented Redux in that element, like so:
function select(state) {
return {companies: state};
}
export default connect(select)(Companies);
Now, despite the element certainly rendering in the browser, and the redux implementation working just fine, I am getting this message in the test results:
Invariant Violation: Could not find "store" in either the context or props of "Connect(Companies)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(Companies)".
I thought I had done this in my routes with this:
let store = createStore(companyApp);
ReactDOM.render(
<Provider store={store}>
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="/companies" component={Companies}>
<Route path=":id" component={Company}/>
</Route>
< /Route>
</Router>
</Provider>, document.getElementById('root'));
but I must be missing something.
This happens because the Companies component is a connected component.
When you try to render the connected component in the test, it warns you that there is no store present. To solve this you can either wrap the Companies component in a Provider with a store specifically made for the test, or, if you just want to test the rendering of the component without worrying about the redux store you can explicitly export the raw component like so:
export class Companies {
...
}
export default connect(select)(Companies);
and in your test
import { Companies } from ./Companies
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render( < Companies companies={[]} / > , div);
});
Testing connected components is described in more detail here http://redux.js.org/docs/recipes/WritingTests.html#connected-components