簡體   English   中英

在 React 中,如何測試組件內的渲染方法

[英]In React, how to test a render method inside a component

我有一個組件,它有一個用於渲染表格的渲染方法。 現在我需要實現一個單元測試來測試該方法( renderTaskAssign() )並查看表格是否成功呈現。 誰能告訴我怎么做? 以下是我希望我可以編寫測試的類的詳細信息。

class TaskAssign extends Component {
  constructor(props) {
    super(props);
    this.renderTaskAssign = this.renderTaskAssign.bind(this);
  }

  renderTaskAssign() {
    if (this.props.data_loading) {
      return (
        <div className="dataloader">
        <ClipLoader
          color={types.LOADING_DATA_COLOR}
          loading={this.props.data_loading}
        />
        </div>);
    } else {
      if (this.props.current_tasks !== '') {
        const item_list = this.props.current_tasks.map((key, index) => {
          return (
              <TableRow key={index}>
              <TableRowColumn>{this.props.current_tasks[index]['pos']}</TableRowColumn>
              <TableRowColumn>{this.props.current_tasks[index]['name']}</TableRowColumn>
              <TableRowColumn>{this.props.current_tasks[index]['completion']}</TableRowColumn>
              <TableRowColumn>{this.props.current_tasks[index]['current_task']}</TableRowColumn>
              <TableRowColumn>{this.props.current_tasks[index]['percent_complete']}</TableRowColumn>
              <TableRowColumn>{this.props.current_tasks[index]['status']}</TableRowColumn>
              <TableRowColumn>Do nothing</TableRowColumn>
              </TableRow>
          );
          })
        return (
          <Table multiSelectable>
          <TableHeader>
            <TableRow>
            <TableHeaderColumn>Pos</TableHeaderColumn>
            <TableHeaderColumn>Installer</TableHeaderColumn>
            <TableHeaderColumn>Work Progress</TableHeaderColumn>
            <TableHeaderColumn>Current Task</TableHeaderColumn>
            <TableHeaderColumn>% Completion</TableHeaderColumn>
            <TableHeaderColumn>Status</TableHeaderColumn>
            <TableHeaderColumn>Add.Info</TableHeaderColumn>
            </TableRow>
          </TableHeader>
            <TableBody>
            {item_list}
            </TableBody>
            </Table>
          );
      }
    }
  }

  render() {
    return (
      <div>
        {this.renderTaskAssign()}
      </div>
    );
  }
}

const mapStateToProps=({ task })=> {
  const { current_tasks, error, data_loading } = task;
  return { current_tasks, error, data_loading };
};

export default connect(mapStateToProps)(TaskAssign);

我嘗試用酶來測試組件,這里是我寫的測試代碼。 我不知道如何在我的情況下測試表格

it("test renderTaskAssign method", () => {
    const renderer = new ShallowRenderer();
    renderer.render(<Provider store={store}>
    <TaskAssign />
    </Provider>);
    const result = renderer.getRenderOutput();
    const taskComponent = new result.type.WrappedComponent();
    taskComponent.props = {
      current_tasks: [
        0: {
          completion: 0.76,
          current_task: 'REASSEMBLE DOORS',
          name: 'A. Smith',
          percent_complete: 0.5,
          pos: 'A1',
          status: 'Good'
        },
        1: {
          completion: 0.66,
          current_task: 'ASEASSEMBLE DOORS',
          name: 'B. Smith',
          percent_complete: 0.7,
          pos: 'B1',
          status: 'Soso'
        }
      ]
    };
    taskComponent.renderTaskAssign()
    console.log(taskComponent.renderTaskAssign().type);
  }
);

實際上,您應該測試組件的行為,而不是它的實現。 從組件的外部來看,您不應該關心它是否具有renderTaskAssign或此函數的作用,而應該關心組件的作用/渲染。

您似乎想要做的是使用特定的 props 測試您的組件,而無需等待您的 Redux 連接將它們注入到您的組件中。 我建議如下,你只測試你的組件,而不是你的商店:

class TaskAssign extends Component {
  constructor(props) {
    super(props);
    this.renderTaskAssign = this.renderTaskAssign.bind(this);
  }

  renderTaskAssign() {
      // some render code
  }

render() {
    return (
      <div>
        {this.renderTaskAssign()}
      </div>
    );
  }
}

const mapStateToProps=({ task })=&gt; {
  const { current_tasks, error, data_loading } = task;
  return { current_tasks, error, data_loading };
};

export default connect(mapStateToProps)(TaskAssign);

export const TaskAssign // <- This enables you to test your component, without the mapStateToProps connection. 

進而 :

import { TaskAssign } from './'; // <-- Import the 'unconnected' version

it("test renderTaskAssign method", () => {
    const renderer = new ShallowRenderer();
    renderer.render( // <- Directly inject your props, not need for an entire store
    <TaskAssign current_tasks={[
        0: {
          completion: 0.76,
          current_task: 'REASSEMBLE DOORS',
          name: 'A. Smith',
          percent_complete: 0.5,
          pos: 'A1',
          status: 'Good'
        },
        1: {
          completion: 0.66,
          current_task: 'ASEASSEMBLE DOORS',
          name: 'B. Smith',
          percent_complete: 0.7,
          pos: 'B1',
          status: 'Soso'
        }
      ]} />
    );
    const result = renderer.getRenderOutput();

    // Test whatever you want : 
    expect(wrapper.is(Table)).toEqual(true);
    expect(wrapper.find(TableRowColumn).length).toEqual(7);
  }
);

現在,從那里(完全超出范圍:-)):

  • 我不明白你的renderTaskAssign函數有什么用
  • 建議盡可能使用功能組件(無生命周期)。
  • 你可以用另一個組件替換你的地圖
  • 你可以使用 babel-plugin-jsx-control-statements 來簡化你的 JSX

所以,我實際上會像這樣編寫你的組件:

const TaskAssign = ({ current_tasks, data_loading }) => (
  <div>
    <Choose>
      <When condition={data_loading} />
        <div className="dataloader">
          <ClipLoader
            color={types.LOADING_DATA_COLOR}
            loading={data_loading}
          />
          </div>
      </When>
      <When condition={current_tasks !== ''}>
        <Table multiSelectable>
          <TableHeader>
            <TableRow>
            <TableHeaderColumn>Pos</TableHeaderColumn>
            <TableHeaderColumn>Installer</TableHeaderColumn>
            <TableHeaderColumn>Work Progress</TableHeaderColumn>
            <TableHeaderColumn>Current Task</TableHeaderColumn>
            <TableHeaderColumn>% Completion</TableHeaderColumn>
            <TableHeaderColumn>Status</TableHeaderColumn>
            <TableHeaderColumn>Add.Info</TableHeaderColumn>
            </TableRow>
          </TableHeader>
            <TableBody>
              <For each="task" of={current_tasks} >
                <SomeItemTableRowComponent task={task} />
              </For>
            </TableBody>
            </Table>
          </When>
        </Choose>
      </div>
    );

const mapStateToProps=({ task })=&gt; {
  const { current_tasks, error, data_loading } = task;
  return { current_tasks, error, data_loading };
};

export default connect(mapStateToProps)(TaskAssign);

export const TaskAssign

希望有幫助

基本上,使用Enzyme您可以檢查內部組件是否已呈現。 例如:

it('should use Table', () => {
    const wrapper = shallow(
      <TaskAssign />
    );
    expect(wrapper.is(Table)).toBe(true);
  });

然后您可以檢查該組件是否包含另一個組件。 例如:

it('should render multiple header columns', () => {
    const wrapper = mount(
      <TaskAssign />
    );
    expect(wrapper.find(TableRowColumn).length).toBe(7);
  });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM