Redux-Form:如何在Jest中模拟formValueSelector

时间:2017-09-26 18:21:22

标签: reactjs jestjs redux-form spy react-redux-form

我有一个组件Demo,其Label取决于redux-form状态中字段的当前值。我使用formValueSelector来获取" param"的当前值。形式状态的字段。它工作正常。但是,在运行npm test时,选择器函数始终返回undefined。我怎么能嘲笑它?

如果我以错误的方式这样做,请告诉我。

我有一个像

这样的组件
class Sample extends React.Component {
render() {
    const {param, state} = this.props;
    const selector = formValueSelector('sampleform');
    return (
        <div>
            <Demo
                name="name"
                label={selector(state, `${param}`)}
            />
        </div>
    );
}

} export default Sample;

,测试代码就像

function setup() {
    const spy = jest.fn();
    const store = createStore(() => ({}));
    const Decorated = reduxForm({ form: 'sampleform' })(Sample);

    const props = {
        "param":"keyOfState",
        "state":{"keyOfState":"Label"}
    }
    const mockedComponent = <Provider store={store}>
        <MuiThemeProvider muiTheme={MuiStyles()}>
            <Decorated {...props}>
                <span></span>
            </Decorated>
        </MuiThemeProvider>
    </Provider>;
    return {
        props,
        mockedComponent}
}
describe('Sample Component', () => {
    it('should render the snapshot', () => {
        const { mockedComponent } = setup()
        const tree = renderer.create(
            mockedComponent
        ).toJSON();
        expect(tree).toMatchSnapshot();
    });
});

2 个答案:

答案 0 :(得分:3)

您没有为formValueSelector提供适当选择所需状态的模拟。

解决方案:选择器需要redux提供的全局状态对象。目前的模拟状态并没有反映出这一点。将模拟更改为预期的形状可以解决问题:

具有这种形状:

{
  form: {
    sampleform: {
      values: {
        keyOfState: "Label"
      }
    }
  }
}

注意:存储在sampleform键中的对象包含更多条目,但它们与模拟无关。

以下是解决问题的复制链接:https://github.com/mjsisley/reduxFormMockIssue

请注意:我是由Matt Lowe执导的。我是与他合作开发过许多其他项目的开发人员。

答案 1 :(得分:0)

对于将来的任何人-如果出于某种原因您实际上需要模拟FormValueSelector,我只是从Helpers模块中为其导出了一个包装器:

request(url, function (error, response, html) {

    var json_list = [];

    if (!error) {
        var $ = cheerio.load(html);

        $('.fixed-recipe-card').each(function () {

            var json = {title: "", description: "", rating: "", ingredients: [], url: ""};

            json.title = $(this).children().last().children().first().text().trim();
            json.description = $(this).children().last().children().first().next().children().last().text().trim();
            json.rating = $(this).children().last().children().first().next().children().first().children().first().attr('data-ratingstars');
            json.url = $(this).children().last().children().first().next().attr('href');

            request(json.url, function (error, response, html) {
                var $ = cheerio.load(html);
                $('.checkList__line').filter(function () {
                    var ingredient = $(this).children().first().children().last().text().trim();
                    if (ingredient !== "Add all ingredients to list") {
                        console.log(ingredient);
                        json.ingredients.push(ingredient);
                    }
                });
            });


            json_list.push(json);

        });
    }

    fs.writeFile('output.json', JSON.stringify(json_list, null, 4), function (err) {
        console.log('success');
    })

    res.send(JSON.stringify(json_list));
});

然后嘲笑那个:

export const tableTypeSelector = formValueSelector('toggle')