首页 > 解决方案 > 如何在玩笑测试时模拟父组件状态

问题描述

我有这个组件,道具是从父组件传递的。成分和活性成分存储在父组件的状态中。

export const IngredientsBox = ({
  ingredients = [],
  activeIngredients = [],
  onAddIngredientHandler,
  onRemoveIngredientHandler,
  onResetIngredientsHandler
}) => {
  return (
    <Div>
      {ingredients.map((name) => {
        return (
          <IngredientButton
            name={name}
            key={name}
            isActive={activeIngredients.includes(name)}
            onAddIngredientHandler={onAddIngredientHandler}
            onRemoveIngredientHandler={onRemoveIngredientHandler}
            />
            );
          })}
          <ResetButton onResetIngredientsHandler={onResetIngredientsHandler}></ResetButton>
    </Div>
  );
};
export const IngredientButton = ({ name, isActive, onAddIngredientHandler, onRemoveIngredientHandler }) => {
  const onClick = isActive ? onRemoveIngredientHandler : onAddIngredientHandler;

  return (
    <Button active={isActive} onClick={() => onClick(name)}>
      {name}
    </Button>
  );
};

我想做的是单独测试这个组件,但无法弄清楚如何在每次方法调用后模仿父组件状态动态改变。

import React from 'react';
import {IngredientsBox} from './IngredientsBox';
import renderer from 'react-test-renderer';

// ingredients and activeIngredients are supposed to imitate parent component state

let ingredients = ['sugar', 'honey', 'mustard', 'watermelon'];
let activeIngredients = [];

const onAddIngredientHandler = (name) => {
  activeIngredients = [...activeIngredients, name]
}
const onRemoveIngredientHandler = (name) => {
  activeIngredients =  activeIngredients.filter((value) => value !== name)
};

test('Button toggle the class on click', () => {
  const component = renderer.create(
    <IngredientsBox  
    ingredients={ingredients} 
    activeIngredients = {activeIngredients} 
    isActive = {activeIngredients.includes(name)} 
    onAddIngredientHandler = {onAddIngredientHandler}
    onRemoveIngredientHandler = {onRemoveIngredientHandler}
    />
  );
    let tree = component.toJSON();
    expect(tree).toMatchSnapshot();

    tree.children[0].props.onClick(); // I expect this to add this element to activeIngredients and it ofcourse works.
    tree = component.toJSON();
    expect(tree).toMatchSnapshot();

    tree.children[0].props.onClick(); // I expect this to remove this element from activeRecipes, it doesn't work, it adds it one more time, and so on. I understand this behaviour is because onClick method was assigned at the beginning and it doesn't change.
    tree = component.toJSON();
    expect(tree).toMatchSnapshot()

})

有没有办法让它表现得像使用 render() 方法的反应组件?所以它每次都以新状态重新渲染?

标签: javascriptreactjstestingjestjs

解决方案


推荐阅读