使用Jest和Enzyme测试反应路由器重定向

时间:2018-09-16 08:35:47

标签: reactjs redirect react-router jestjs enzyme

我有一个使用react-router的简单React组件,如果用户无权查看特定路由,它将重定向用户:

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {permission: false};
  }

  render() {
    return (
      <Switch>
        <Route exact path="/users">
          <h2>A list of users</h2>
        </Route>
        <Route path="/users/:userId">
          {({match}) => this.state.permission ? <h1>{match.params.userId}</h1> : <Redirect to="/users" />}
        </Route>
      </Switch>
    );
  }
}

我正在尝试使用Jest和酶访问/users/:userId时测试不同的情况,但是当用户获得许可时,我无法使测试成功。

我的测试如下:

describe("render()", () => {
  describe("when route is /users/:userId", () => {
    let wrapper;
    let app;
    beforeEach(() => {
      wrapper = mount(
        <MemoryRouter initialEntries={["/users/1"]}>
          <App />
        </MemoryRouter>
      );
      app = wrapper.find(App).instance();
    });

    describe("when user has permission", () => {
      beforeEach(() => {
        app.setState({permission: true});
      });

      it("should show users id", () => {
        expect(wrapper.exists("h1")).toBe(true);
      });
    });

    describe("when user doesn't have permission", () => {
      beforeEach(() => {
        app.setState({permission: false});
      });

      it("should redirect to users list", () => {
        expect(wrapper.exists("h2")).toBe(true);
      });
    });
  });
});

第一个测试失败,而第二个成功。我在第一个测试中使用了console.log(wrapper.debug());,它表明该组件正在渲染第一个路由(即,被重定向),并且已经打印了状态,因此可以看到setState调用是工作。

我应该如何重写测试以使其正常工作?

1 个答案:

答案 0 :(得分:1)

问题

初始位置设置为/users/1,但是在首次安装组件时,它将呈现Redirect,该位置将位置设置为/users

然后将

permission设置为true,但是由于位置为/users,结果为<h2>A list of users</h2>


解决方案

permission设置为true后,将位置设置为/users/1,以便该位置正确并且测试成功呈现<h1>1</h1>

describe("render()", () => {
  describe("when route is /users/:userId", () => {
    let wrapper;
    let app;
    beforeEach(() => {
      wrapper = mount(
        <MemoryRouter initialEntries={["/users/1"]}>
          <App />
        </MemoryRouter>
      ); // the Redirect sets location to /users during the initial render
      app = wrapper.find(App).instance();
    });

    describe("when user has permission", () => {
      beforeEach(() => {
        app.setState({permission: true});
        wrapper.instance().history.replace('/users/1'); // replace the MemoryRouter location with /users/1
        wrapper.update(); // update the wrapper with the changes
      });

      it("should show users id", () => {
        expect(wrapper.exists("h1")).toBe(true); // SUCCESS
      });
    });

    describe("when user doesn't have permission", () => {
      beforeEach(() => {
        app.setState({permission: false});
      });

      it("should redirect to users list", () => {
        expect(wrapper.exists("h2")).toBe(true);
      });
    });
  });
});