首页 > 解决方案 > 基于本地存储断言组件行为的更好方法

问题描述

我有一个基于类的组件,我在其中查找 componentDidMount 的 localstorage 中的变量。

如果它存在,我会渲染其他孩子,我会渲染一个表单

我如何为这个组件编写测试用例?我想通过更改本地存储来测试我的组件行为。

标签: reactjstypescriptjestjsenzyme

解决方案


为读者添加答案

// My Component
export class Test extends Component {
  public state = { isAvailable: false }
  public componentDidMount() {
    const isAvailable = window.localStorage.getItem("is-agreed") === "true";
    if (isAvailable) {
      this.setState({ isAvailable: true });
      return;
    }
  }
  public render() {
    const template = <p>Not available</p>
    if (this.state.isAvailable) template = this.props.children;
    return template; 
  }
}

// My Test file
describe("Components/Test", () => {
  let wrapper: ReactWrapper;
  const store = configureStore();

  const getComponent = () => {
    const mockStore = store({ data: { something: something } });
    return mount(
      <Provider store={mockStore}>
        <Test>
          <p id="testChildren">test</p>
        </Test>
      </Provider>,
    );
  };

  // If I mount component in beforeEach I'm not able to change the localStorage since the lifecyle method is called before "it".
  // So I'm mounting the component in each test case after changing the local storage.
  // beforeEach(() => {
  //   wrapper = getComponent(); 
  // });

  afterEach(() => {
    wrapper.unmount();
  });

  it("should return the children when agreed", () => {
    localStorage.setItem("is-agreed", "true");
    wrapper = getComponent();
    expect(wrapper.exists("#testChildren")).toBeTruthy();
  });

  it("should return the children when not agreed", () => {
    localStorage.setItem("is-agreed", "false");
    wrapper = getComponent();
    expect(wrapper.exists("#testChildren")).toBeFalsy();
  });
});

// Local storage mock defined globally in setupTests.ts
var localStorageMock = (function() {
  var store: any = {};
  return {
    getItem: function(key: string) {
      return store[key];
    },
    setItem: function(key: string, value: string) {
      store[key] = value.toString();
    },
    clear: function() {
      store = {};
    },
    removeItem: function(key: string) {
      delete store[key];
    },
  };
})();

Object.defineProperty(window, "localStorage", { value: localStorageMock });

推荐阅读