Hello guys, after of all, thanks for the great job!
I have a little problem when i need testing functions after add lib for translate. I reproduce code and console.log for clear the idea.
Code working:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
class AddAccesses extends Component {
state = { isAccessEnabled: false }
toggleInputAccess = () => {
const { isAccessEnabled } = this.state;
this.setState({
isAccessEnabled: !isAccessEnabled
});
}
render() {
const { isAccessEnabled } = this.state;
const { t } = this.props;
return (
<div>
<Box
data-testid="BoxAccess"
bg={isAccessEnabled}
onClick={this.toggleInputAccess}
>
{t('add_accesses_button_search_role_guide_off')}
</Box>
<Tooltip span text={t('add_accesses_tooltip_role_guide_off')} />
</div>
);
}
}
AddAccesses.propTypes = {
t: PropTypes.func.isRequired,
};
const mapStateToProps = state => ({
systems: state.systems,
accesses: state.accesses,
});
export default connect(
mapStateToProps, { fetchIdentities },
)(AddAccesses);
Test working:
beforeEach(() => {
store = mockStore(initialState);
wrapper = shallow(
<AddAccessesCaseEnzyme store={store} />,
).childAt(0).dive();
instance = wrapper.instance();
});
it('should find BoxAccess, BoxIdentity, BoxCriticalComponent, BoxAccessKit', () => {
console.log(wrapper.debug());
expect(wrapper.find('[data-testid="BoxAccess"]')).toHaveLength(1);
});
Console:
<Box data-testid="BoxAccess" bg={isAccessEnabled} onClick={this.toggleInputAccess}>{t('add_accesses_button_search_role_guide_off')}</Box>
| ^
192 | <Tooltip span text={t('add_accesses_tooltip_role_guide_off')} />
So far, so good. But when i add another layer for translate in component stop work the test.
Code working with import { withNamespaces } from 'react-i18next';:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { withNamespaces } from 'react-i18next';
class AddAccesses extends Component {
state = { isAccessEnabled: false }
toggleInputAccess = () => {
const { isAccessEnabled } = this.state;
this.setState({
isAccessEnabled: !isAccessEnabled
});
}
render() {
const { isAccessEnabled } = this.state;
const { t } = this.props;
return (
<div>
<Box
data-testid="BoxAccess"
bg={isAccessEnabled}
onClick={this.toggleInputAccess}
>
{t('add_accesses_button_search_role_guide_off')}
</Box>
<Tooltip span text={t('add_accesses_tooltip_role_guide_off')} />
</div>
);
}
}
AddAccesses.propTypes = {
t: PropTypes.func.isRequired,
};
const mapStateToProps = state => ({
systems: state.systems,
accesses: state.accesses,
});
export default withNamespaces()(connect(
mapStateToProps, { fetchIdentities },
)(AddAccesses));
Test with shallow() don't work:
beforeEach(() => {
store = mockStore(initialState);
wrapper = shallow(
<Provider store={store}>
<I18nextProvider i18n={i18n}>
<BrowserRouter>
<Switch>
<AddAccessesCaseEnzyme />
</Switch>
</BrowserRouter>
</I18nextProvider>
</Provider>,
).childAt(0).dive();
instance = wrapper.instance();
});
it('should user does not selected benefited', () => {
history.push('/benefited');
expect(window.location.href).toBe('http://localhost/benefited');
});
it('should find BoxAccess, BoxIdentity, BoxCriticalComponent, BoxAccessKit', () => {
expect(wrapper.find('[data-testid="BoxAccess"]')).toHaveLength(3);
});
it('toggleInputIdentities and enableInputIdentities function should update state as expected', () => {
console.log(wrapper.debug());
instance.toggleInputAccess();
});
Console:
FAIL app/javascript/src/spec/javascript/packs/components/organisms/add_accesses_case_enzyme.spec.js
Testing AddAccesses component
✓ should user does not selected benefited (144ms)
✕ should find BoxAccess (10ms)
✕ toggleInputAccess function should update state as expected (13ms)
● Testing AddAccesses component › should find BoxAccess
expect(received).toHaveLength(expected)
Expected length: 3
Received length: 0
Received object: {}
100 |
101 | it('should find BoxAccess', () => {
> 102 | expect(wrapper.find('[data-testid="BoxAccess"]')).toHaveLength(3);
| ^
103 | });
104 |
105 | it('toggleInputAccess function should update state as expected', () => {
at Object.toHaveLength (app/javascript/src/spec/javascript/packs/components/organisms/add_accesses_case_enzyme.spec.js:102:55)
● Testing AddAccesses component › toggleInputAccess function should update state as expected
TypeError: instance.toggleInputAccess is not a function
105 | it('toggleInputAccess function should update state as expected', () => {
106 | console.log(wrapper.debug());
> 107 | instance.toggleInputAccess();
| ^
108 | expect(instance.state.isAccessEnabled).toBe(true);
109 | });
110 |
at Object.toggleInputAccess (app/javascript/src/spec/javascript/packs/components/organisms/add_accesses_case_enzyme.spec.js:107:14)
console.log app/javascript/src/spec/javascript/packs/components/organisms/add_accesses_case_enzyme.spec.js:106
<ContextProvider value={{...}}>
<BrowserRouter>
<Switch>
<LoadNamespace(Connect(AddAccesses)) />
</Switch>
</BrowserRouter>
</ContextProvider>
Test with mount() don't work:
beforeEach(() => {
store = mockStore(initialState);
wrapper = mount(
<Provider store={store}>
<I18nextProvider i18n={i18n}>
<BrowserRouter>
<Switch>
<AddAccessesCaseEnzyme />
</Switch>
</BrowserRouter>
</I18nextProvider>
</Provider>,
);
instance = wrapper.instance();
});
it('should user does not selected benefited', () => {
history.push('/benefited');
expect(window.location.href).toBe('http://localhost/benefited');
});
it('should find BoxAccess', () => {
expect(wrapper.find('[data-testid="BoxAccess"]')).toHaveLength(3);
});
it('toggleInputAccess function should update state as expected', () => {
console.log(wrapper.debug());
instance.toggleInputAccess();
expect(instance.state.isAccessEnabled).toBe(true);
});
Console:
<Provider store={{...}}>
<I18nextProvider i18n={{...}}>
<BrowserRouter>
<Router history={{...}}>
<Switch>
<LoadNamespace(Connect(AddAccesses)) location={{...}} computedMatch={{...}}>
<WithMergedOptions i18n={{...}} defaultNS={[undefined]} reportNS={[undefined]} lng="pt" t={[Function: bound t]} location={{...}} computedMatch={{...}}>
<LoadNamespace i18n={{...}} t={[Function: bound t]} lng="pt" i18nOptions={{...}} defaultNS={[undefined]} reportNS={[undefined]} location={{...}} computedMatch={{...}}>
<WithMergedOptions(NamespacesConsumerComponent) ns={[undefined]} i18n={{...}} t={[Function: bound t]} lng="pt" i18nOptions={{...}} defaultNS={[undefined]} reportNS={[undefined]} location={{...}} computedMatch={{...}}>
<WithMergedOptions i18n={{...}} defaultNS={[undefined]} reportNS={[undefined]} lng="pt" t={[Function: bound t]} ns={[undefined]} i18nOptions={{...}} location={{...}} computedMatch={{...}}>
<NamespacesConsumerComponent i18n={{...}} t={[Function: bound t]} lng="pt" i18nOptions={{...}} defaultNS={[undefined]} reportNS={[undefined]} ns={[undefined]} location={{...}} computedMatch={{...}}>
<Connect(AddAccesses) tReady={true} i18n={{...}} t={[Function: fixedT]} lng="pt" i18nOptions={{...}} defaultNS={[undefined]} reportNS={[undefined]} location={{...}}
computedMatch={{...}}>
<AddAccesses tReady={true} i18n={{...}} t={[Function: fixedT]} lng="pt" i18nOptions={{...}} defaultNS={[undefined]} reportNS={[undefined]} location={{...}} computedMatch={{...}} systems={{...}} accesses={{...}} selectedBenefited={{...}} fetchIdentities={[Function]} fetchCriticalComponents={[Function]} fetchSystems={[Function]} setSelectedAccesses={[Function]} updateSelectedAccesses={[Function]}>
<div>
<styled.div borderBottom={true} alignItems={true}>
<StyledComponent borderBottom={true} alignItems={true} forwardedComponent={{...}} forwardedRef={{...}}>
<div className="sc-dxgOiQ KKGvM">
<Link to="/helpdesk">
<a onClick={[Function: onClick]} href="/helpdesk">
<styled.img src="test-file-stub">
<StyledComponent src="test-file-stub" forwardedComponent={{...}} forwardedRef={{...}}>
<img src="test-file-stub" className="sc-ckVGcZ dvqRth" />
</StyledComponent>
</styled.img>
</a>
</Link>
</div>
</StyledComponent>
</styled.div>
<styled.div spaceAround={true}>
<StyledComponent spaceAround={true} forwardedComponent={{...}} forwardedRef={{...}}>
<div className="sc-dxgOiQ gfxngO">
<styled.div flexEnd={true}>
<StyledComponent flexEnd={true} forwardedComponent={{...}} forwardedRef={{...}}>
<div className="sc-dxgOiQ kgTxfX">
<styled.button data-testid="BoxAccess" bg={{...}} onClick={[Function]}>
<StyledComponent data-testid="BoxAccess" bg={{...}} onClick={[Function]} forwardedComponent={{...}} forwardedRef={{...}}>
<button data-testid="BoxAccess" onClick={[Function]} className="sc-chPdSV gDtCiS">
Eu sei o nome ou parte do nome do perfil
</button>
In short, when i add lib i18next-react the test gets lost, and i don't get access for execute the function
<button data-testid="BoxAccess" onClick={[Function]} className="sc-chPdSV gDtCiS">
Eu sei o nome ou parte do nome do perfil
</button>
@ljharb Hello, help us please.
@drd-2rcl Instead of wrapping the component with your provider, use the wrappingComponent option, like this:
function WrapWithProviders({ children }) {
return (
<Provider store={store}>
<I18nextProvider i18n={i18n}>
<BrowserRouter>
<Switch>
{children}
</Switch>
</BrowserRouter>
</I18nextProvider>
</Provider>
);
}
const wrapper = shallow(<AddAccessesCaseEnzyme />, {
wrappingComponent: WrapWithProviders,
});
@ljharb did this answer you provide change?
Most helpful comment
@drd-2rcl Instead of wrapping the component with your provider, use the
wrappingComponentoption, like this: