0

I am testing a react component which renders another component which calls an endpoint and returns some data and is displayed, i want to know how i can mock the component that calls the endpoint and return dummy data for each test

This is the component i am testing

class MetaSelect extends React.Component {
    render() {
        console.log('metaselect render', MetadataValues);
        return (
             <MetadataValues type={this.props.type}> 
                {({ items, isLoading }) => (
                    <>
                        {isLoading ? (
                            <Icon variant="loadingSpinner" size={36} />
                        ) : (
                            <Select {...this.props} items={items} placeholder="Please select a value" />
                        )}
                    </>
                )}
            </MetadataValues> 
        );
    }
}

MetaSelect.propTypes = {
    type: PropTypes.string.isRequired
};

I want to mock the MetadataValues in my tests, this is the metadataValues.js file

class MetadataValues extends React.Component {
    state = {
        items: [],
        isLoading: true
    };

    componentDidMount() {
        this.fetchData();
    }

    fetchData = async () => {
        const items = await query(`....`);
        this.setState({ items, isLoading: false });
    };

    render() {
        return this.props.children({ items: this.state.items, isLoading: this.state.isLoading });
    }
}

MetadataValues.propTypes = {
    type: PropTypes.string.isRequired,
    children: PropTypes.func.isRequired
};

This is my metaSelect.test.js file

jest.mock('../MetadataValues/MetadataValues');


describe.only('MetaSelect component', () => {

    fit('Should display spinner when data isnt yet recieved', async () => {
        MetadataValues.mockImplementation( ()=> { <div>Mock</div>});
        
        const wrapper = mount(<MetaSelect type="EmployStatus"/>);          
        expect( wrapper.find('Icon').exists() ).toBeTruthy();
    });
    
});

Im guessing i need to add something in the MetadataValues.mockImplementation( )
but im not sure what i should add to mock the component correctly

2
  • I think you just need to use setState - github.com/airbnb/enzyme/blob/master/docs/api/ShallowWrapper/… Commented Feb 18, 2019 at 13:20
  • To sway you the other way, have you thought about how you're testing the edge cases of the query? That could resolve to include 0, 1, or many items or reject with an error that isn't handled yet. Commented Feb 18, 2019 at 19:16

2 Answers 2

2

If you only need one version of the mock in your test this should be enough:

jest.mock('../MetadataValues/MetadataValues', ()=> ()=> <div>Mock</div>);

If you need to different mock behaviour you need to mock it like this

import MetadataValues from '../MetadataValues/MetadataValues'
jest.mock('../MetadataValues/MetadataValues', ()=> jest.fn());

it('does something', ()={
   MetadataValues.mockImplementation( ()=> { <div>Mock1</div>});
})

it('does something else', ()={
  MetadataValues.mockImplementation( ()=> { <div>Mock2</div>});
})


Sign up to request clarification or add additional context in comments.

2 Comments

should it be : MetadataValues.mockImplementation( ()=> ( <div>Mock1</div>)) ? it miss the return
MyOwnComponent.mockImplementation( ()=> { <div>Mock2</div>}) gives me an error such as Property 'mockImplementation' does not exist on type. This answer makes sense to me, but I'm unsure what I'm doing differently than this example.
0

what about using shallow() instead of mount()?

const mockedItems = [{.....}, {...}, ...];

it('shows spinner if data is loading', () => {
    const wrapper = shallow(<MetaSelect type={...} /*other props*/ />);
    const valuesChildren = wrapper.find(MetadataValues).prop('children');
    const renderResult = valuesChildren(mockedItems, true);
    expect(renderResult.find(Icon)).toHaveLength(1);
    expect(renderResult.find(Icon).props()).toEqual({
        variant: "LoadingSpinner", // toMatchSnapshot() may be better here
        size: 36,
    });
});

This not only makes mocking in natural way but also has some benefits

it('passes type prop down to nested MetadataValues', () => {
    const typeMocked = {}; // since it's shallow() incorrect `type` does not break anything
    const wrapper = shallow(<MetaSelect type={typeMocked} >);
    expect(wrapper.find(MetadataValues).prop('type')).toStrictEqual(typeMocked);
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.