TrueCar / react-launch-darkly

Simple component helpers to support LaunchDarkly in your React app.
MIT License
76 stars 20 forks source link

unable to mock <FeatureFlag> with jest #69

Closed tekgal closed 5 years ago

tekgal commented 6 years ago

I have component as specified below. I am unable to unit test the code within the FeatureFlag tag using jest.mock . My intent is to mock true/false response similar to LaunchDarkly and be able to test and get coverage on "renderFeatureCallback" and "renderDefaultCallback".


import React from 'react';
import {FeatureFlag} from 'react-launch-darkly';
import * as styles from './EnvRevisionButton.style';

const TestComponent=({btnName, onClickFunction, featureFlag})=> {
    return (
        <span>
            {<FeatureFlag
                flagKey={featureFlag}
                renderFeatureCallback={
                    () => {
                        return (
                            <button className='btn pull-right btn-primary btn-block'
                                    disabled={false}
                                    id={'btn::' + btnName}
                                    value={btnName}
                                    onClick={onClickFunction:null}
                                    width='100%'
                            >{btnName}</button>
                        );
                    }
                }
                renderDefaultCallback={() => {
                    return (
                        <button className='btn pull-left btn-primary btn-block'
                                disabled={true}
                                value={btnName}
                                width='100%'
                        >{btnName}</button>
                    );
                }
                }>
            </FeatureFlag>
            }
        </span>
    );
};

export default TestComponent;

TestComponent.propTypes = {
    btnName: PropTypes.string.isRequired,
    onClickFunction: PropTypes.func.isRequired,
    featureFlag: PropTypes.string.isRequired,
};```
jacobmoretti commented 6 years ago

@tech-gal Are you trying to test that the proper callbacks are called depending on the value of the feature flag? If so, I wouldn't really recommend testing that mechanism as its covered by this library. If you really want to test the full-stack of operations, LaunchDarkly service -> react-launch-darkly -> your app, I'd recommend an integration level test for that.

Otherwise if you're just trying to test each individual callback, there are two ways to handle that: 1) Abstract out your functions for renderFeatureCallback and renderDefaultCallback, then call those individually to assert your expectation 2) Call the props on directly for your assertion:

const wrapper = shallow(<TestComponent />);
const featureFlag = wrapper.find(FeatureFlag);
expect(featureFlag.props().renderFeatureCallback()).toEqual(...);
jacobmoretti commented 5 years ago

Closing issue for lack of activity.

danielo515 commented 4 years ago

In my case what I want is just to avoid calls to the backend during testing and not having to wrap my tests with the launch-darkly provider. Is there any example of how to do this in jest?

sethbattin commented 4 years ago

@danielo515 Certainly. You could configure your test boilerplate to disable updates from the service, and manually specify all your flag values in bootstrap. It's almost the same use case as the SSR section of our docs: https://github.com/TrueCar/react-launch-darkly#disable-launchdarkly-js-client-initialization-preventing-xhrs

If your test code doesn't permit that, then jest definitely allows you to override the underlaying library. https://jestjs.io/docs/en/manual-mocks#mocking-node-modules You could mock at whatever level makes sense for your test. The ldclient-js library is the thing that handles comms with launch darkly's service. Or launchdarkly-js-client-sdk, if you're using the newer version https://github.com/TrueCar/react-launch-darkly/blob/master/package.json#L51

edit to clarify, there's no way to avoid using the provider unless you mock the system so hard that you aren't testing anything related to flags. That's fine if its what you want to do; just define your components in such a way that you avoid touching the components from this library altogether. i.e. test whatever is rendered inside of renderFeatureCallback. If you want a more integrated test, use the provider but hardcode the bootstrap values.

danielo515 commented 4 years ago

Thanks for your answer @sethbattin. In my case seems that some code already adds the provider to the tests, so totally overriding it was not an option. What I ended doing was to just use the normal jest semantics for mocking modules and unmock them where having the real implementation was critical. Sadly we're using an old version of the library, so following the docs for SSR is troublesome. Thanks in any way.