简体   繁体   English

用玩笑和酵素测试按钮

[英]Testing a button with jest and enzyme

In my React-Native application I have a button component which is used as follows. 在我的React-Native应用程序中,我有一个按钮组件,其用法如下。

// primary button (default button)
<Button
  text='Continue'
  onPress={() => this.onContinue()}
/>

// secondary button
<Button
  type='Secondary'
  text='Continue'
  onPress={() => this.onContinue()}
/>

// disabled button
<Button
  text='Continue'
  disabled={true}
  onPress={() => this.onContinue()}
/>

I wrote the following tests for these. 我为此编写了以下测试。

import { shallow } from 'enzyme';
import React from 'react';
import Button from '../../src/components/button';

describe('Button', () => {
  it('expect to render a primary button component', () => {
    const mockLabel = 'Test Button';
    const wrapper = shallow(<Button label={mockLabel} />);
    expect(wrapper).toMatchSnapshot('primary button snapshot');
  });

  it('expect to render a secondary button component', () => {
    const type = Button.Types.SECONDARY;
    const mockLabel = 'Test Button';
    const wrapper = shallow(<Button type={type} label={mockLabel} />);
    expect(wrapper).toMatchSnapshot('secondary button snapshot');
  });

  it('expect to render a disabled button component', () => {
    const disabled = true;
    const mockLabel = 'Test Button';
    const wrapper = shallow(<Button label={mockLabel} disabled={disabled} />);
    expect(wrapper).toMatchSnapshot();
  });
});

Is this the proper way to write the tests? 这是编写测试的正确方法吗? It works properly though, but do these tests cover the scenarios properly?? 虽然它可以正常工作,但是这些测试是否可以正确涵盖方案??

Here is my button component. 这是我的按钮组件。 How can I check if the type is Primary or Secondary? 如何检查类型是主要还是次要? If the button disabling works properly? 如果禁用按钮功能正常? Does onPress() works as expected?? onPress()是否按预期工作? Any help will be appreciated. 任何帮助将不胜感激。

import React, { Component } from 'react';
import { StyleSheet, TouchableOpacity } from 'react-native';

import { TextLabel } from '../components';
import colors from '../res/colors';

class Button extends Component<IProps> {
  static defaultProps: IProps;

  static Types = {
    PRIMARY: 'primary',
    SECONDARY: 'secondary',
  };

  state = {
    pressed: false,
  };

  handlePressIn = () => {
    this.setState({ pressed: true });
  }

  handlePressOut = () => {
    this.setState({ pressed: false });
  }

  buttonStyles = () => {
    const { pressed } = this.state;
    const { type, disabled } = this.props;

    if (type === Button.Types.PRIMARY) {
      if (disabled) return styles.primaryButtonDisabled;
      if (!pressed) return styles.primaryButtonDefault;
      if (pressed) return styles.primaryButtonPressed;
    }

    if (type === Button.Types.SECONDARY) {
      if (disabled) return styles.secondaryButtonDisabled;
      if (!pressed) return styles.secondaryButtonDefault;
      if (pressed) return styles.secondaryButtonPressed;
    }
  }

  textStyles = () => {
    const { pressed } = this.state;
    const { type, disabled } = this.props;

    if (type === Button.Types.PRIMARY) return styles.primaryText;

    if (type === Button.Types.SECONDARY) {
      if (disabled) return styles.secondaryTextDisabled;
      if (!pressed) return styles.secondaryTextDefault;
      if (pressed) return styles.secondaryTextPressed;
    }
  }

  render() {
    const {
      disabled,
      text,
      buttonStyle,
      onPress,
    } = this.props;

    return (
      <TouchableOpacity
        onPress={() => onPress()}
        activeOpacity={1}
        onPressIn={this.handlePressIn}
        onPressOut={this.handlePressOut}
        disabled={disabled}
        style={[styles.button, this.buttonStyles(), buttonStyle]}
      >
        <TextLabel
          type={TextLabel.Types.BUTTON_LBL}
          style={[styles.text, this.textStyles()]}
          label={text}
        />
      </TouchableOpacity>
    );
  }
}

const styles = StyleSheet.create({
  button: {
    borderRadius: 4,
    borderWidth: 1,
    justifyContent: 'center',
    // position: 'absolute',
    height: 48,
    width: '100%',
    marginTop: 20,
    marginBottom: 20,
  },
  primaryButtonDefault: {
    backgroundColor: colors.primary,
    borderColor: colors.primary,
  },
  primaryButtonPressed: {
    backgroundColor: colors.darkRed,
    borderColor: colors.darkRed,
  },
  primaryButtonDisabled: {
    backgroundColor: colors.gray,
    borderColor: colors.gray,
  },
  secondaryButtonDefault: {
    borderColor: colors.primary,
  },
  secondaryButtonPressed: {
    borderColor: colors.darkRed,
  },
  secondaryButtonDisabled: {
    borderColor: colors.gray,
  },
  text: {
    textAlign: 'center',
    textTransform: 'uppercase',
  },
  primaryText: {
    color: colors.white,
  },
  secondaryTextDefault: {
    color: colors.primary,
  },
  secondaryTextPressed: {
    color: colors.darkRed,
  },
  secondaryTextDisabled: {
    color: colors.gray,
  },
});

export interface IProps {
  disabled?: boolean;
  text: string;
  type?: string;
  buttonStyle?: object;
  onPress: Function;
}

Button.defaultProps = {
  disabled: false,
  text: '',
  type: Button.Types.PRIMARY,
  buttonStyle: {},
  onPress: () => {},
};

export default Button;

Snapshot testing is different than unit testing. 快照测试不同于单元测试。

Snapshot testing is useful to understand the differences in render output for a given component. 快照测试对于了解给定组件的渲染输出的差异很有用。 Especially during a code review exercise or when browsing through the source control history of a project. 尤其是在代码审查练习中或浏览项目的源代码管理历史记录时。 They do not however guarantee a given behavior. 但是,它们不能保证给定的行为。

What you have written are snapshot tests, it would be great to complement them with unit tests. 您所写的是快照测试,最好用单元测试来补充它们。 In your case, you would need to test the inner workings of your Button component: 在您的情况下,您需要测试Button组件的内部工作原理:

Given a certain set of parameters (for example your 3 scenarios), is the render() function of Button rendering the expected code. 给定一组特定的参数(例如您的3个场景), Buttonrender()函数将呈现所需的代码。 Since you have not posted the code for your Button component, I can't help you write these tests. 由于您尚未发布Button组件的代码,因此我无法帮助您编写这些测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM