Следите за именем пути в истории в тесте React- JS - PullRequest
1 голос
/ 19 февраля 2020

Мое приложение имеет панель инструментов, которая содержит панель поиска. При заданном поисковом вводе функция доставляет информацию о найденных поисковых запросах (тип цели один или тип два). Если доставлен один из этих целевых типов, приложение направляется в / app / type-one или / app / type-two. Я просто хочу отследить history.location.path от "/" до "/ app / type-one" или "/ app / type-two". Связанный тест использует Jest, и его expexct () не может увидеть изменения в history.location.path. На самом деле я вижу изменения при отладке компонента во время теста.

Тестируемый компонент:

import React from "react";
import { makeStyles, fade } from "@material-ui/core/styles";
import Toolbar from "@material-ui/core/Toolbar";
import Tooltip from "@material-ui/core/Tooltip";
import IconButton from "@material-ui/core/IconButton";
import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
import ChevronRightIcon from "@material-ui/icons/ChevronRight";
import logo from "../../logo_72dpi.png";
import kicon from "../../kicon_72dpi.png";
import SearchIcon from "@material-ui/icons/Search";
import { InputBase } from "@material-ui/core";
import { useSomeContext } from "../../context/some/some_context";
import { withRouter } from "react-router-dom";
import { Link as RouterLink } from "react-router-dom";
import { Icon } from "@iconify/react";
import logoutIcon from "@iconify/icons-mdi/logout";

const useStyles = makeStyles(theme => ({
  // CSS code
}));

const Navbar = props => {
  const drawerState = props.drawerState;
  const toggleDrawer = props.toggleDrawer;
  const zoneButtons = props.zoneButtons;
  const searchField = props.searchField;

  const someContext = useSomeContext();
  const { getDocumentType, resetAuthenticated } = someContext;
  const classes = useStyles();

  let searchfieldvalue = null;

  const handleLoad = e => {
    searchfieldvalue = e.target.value;
  };

  const handleSearchbarClick = async e => {
    const documentType = await getDocumentType(searchfieldvalue);
    if (documentType) {
      routeToPage(documentType);
    }
  };

  const handleKeyPressSearchbar = async e => {
    if (e.charCode === 13 && searchfieldvalue) {
      const documentType = await getDocumentType(searchfieldvalue);
      if (documentType) {
        routeToPage(documentType);
      }
    }
  };

  const routeToPage = documentType => {
    if ((documentType = "TypeOne")) {
      props.history.push("/app/type-one");
    } else if ((documentType = "TypeTwo")) {
      props.history.push("/app/type-two");
    }
  };

  const logout = () => {
    resetAuthenticated();
    props.history.push("/");
  };

  return (
    <>
      <Toolbar>
        <Toolbar className={classes.title}>
          <div style={classes.logoHorizontallyCenter}>
            <IconButton
              aria-label="delete"
              className={classes.margin}
              component={RouterLink}
              to="/app"
            >
              <img src={logo} className={classes.logo} alt="logo missing" />
            </IconButton>
          </div>
        </Toolbar>
        {zoneButtons}
        {searchField && (
          <div className={classes.search}>
            <div className={classes.searchIcon}>
              <img src={kicon} className={classes.klogo} alt="K" />
            </div>
            <InputBase
              placeholder="Search…"
              classes={{
                root: classes.inputRoot,
                input: classes.inputInput
              }}
              onChange={handleLoad}
              onKeyPress={handleKeyPressSearchbar}
              inputProps={{ "aria-label": "search" }}
            />
            <IconButton
              aria-label="delete"
              className={classes.margin}
              onClick={() => handleSearchbarClick()}
            >
              <SearchIcon />
            </IconButton>
          </div>
        )}
        <Tooltip title="Logout">
          <IconButton
            color="inherit"
            onClick={() => {
              logout();
            }}
          >
            <Icon icon={logoutIcon} />
          </IconButton>
        </Tooltip>
        {toggleDrawer && (
          <IconButton
            edge="end"
            className={classes.menuButton}
            color="inherit"
            onClick={toggleDrawer("right", !drawerState.right.state)}
          >
            {drawerState.right.state ? (
              <ChevronRightIcon />
            ) : (
              <ChevronLeftIcon />
            )}
          </IconButton>
        )}
      </Toolbar>
    </>
  );
};

export default withRouter(Navbar);

Тестовое значение c выглядит следующим образом

import React from "react";
import { Router, MemoryRouter, Route } from "react-router-dom";
import { render, ReactDOM } from "react-dom";
import Navbar from "./navbar";
import { createMemoryHistory } from "history";
import TestRenderer from "react-test-renderer";
import * as SomeContext from "../../context/some/some_context";
import { act, TestUtils } from "react-dom/test-utils";
import "@testing-library/jest-dom/extend-expect";

const drawerState = {
  right: { size: 340, state: true }
};

let container;
let history;

const componentUnderTest = (
  <Navbar
    drawerState={drawerState}
    toggleDrawer={jest.fn()}
    zoneButtons={jest.fn()}
    searchField="true"
  />
);

let actualRenderedSnippet;

beforeEach(() => {
  history = createMemoryHistory();
  container = document.createElement("div");
  document.body.appendChild(container);
  defaultContextValues.getDocumentType.mockClear();
  defaultContextValues.resetAuthenticated.mockClear();
});

const defaultContextValues = {
  getDocumentType: jest.fn(),
  resetAuthenticated: jest.fn()
};
test("should route to type-one, when documentType is TypeOne", () => {
  const documentTypeOneConfig = givenDocumentTypeOne();
  whenRenderingNavbar(documentTypeOneConfig);
  andInputAndEnterIsPresent();
  thenNavbarRoutesToTypeOne();
});

const givenDocumentTypeOne = () => {
  return {
    getDocumentType: jest.fn(x => {
      return "TypeOne";
    })
  };
};


const whenRenderingNavbar = testValues => {
  const testContextValues = { ...defaultContextValues, ...testValues };
  jest
    .spyOn(SomeContext, "useSomeContext")
    .mockImplementation(() => testContextValues);

  const testRenderer = TestRenderer.create(
    <MemoryRouter>
      <Router history={history}>{componentUnderTest}</Router>
    </MemoryRouter>
  );
  container = testRenderer.root;
};

const andInputAndEnterIsPresent = async () => {
  const input = container.findByType("input");
  const inputParent = input.parent;

  input.props.onChange({ target: { value: "Test" } });
  inputParent.props.onKeyPress({ charCode: 13 });
};

// This is always "/" instead of "/app/type-one"
const thenNavbarRoutesToTypeOne = () => {
  expect(history.location.pathname).toBe("/app/type-one");
};

Это пакет. json

{
  "name": "app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@aws-amplify/api": "^1.2.4",
    "@aws-amplify/auth": "^1.5.0",
    "@aws-amplify/pubsub": "^1.2.4",
    "@date-io/date-fns": "^1.3.13",
    "@iconify/icons-mdi": "^1.0.65",
    "@iconify/react": "^1.1.1",
    "@material-ui/core": "^4.9.2",
    "@material-ui/icons": "^4.5.1",
    "@material-ui/pickers": "^3.2.8",
    "aws-amplify": "^1.2.4",
    "aws-amplify-react": "^2.5.4",
    "axios": "^0.19.1",
    "date-diff": "^0.2.1",
    "date-fns": "^2.9.0",
    "moment": "^2.24.0",
    "react-helmet": "^5.2.1",
    "react-router-dom": "^5.1.2",
    "react-scripts": "^3.3.1"
  },
  "scripts": {
    "test": "react-scripts test --useStderr --coverage"
  },
  "husky": {
    "hooks": {
      "pre-push": "npm run push-hook"
    }
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "concurrently": "^5.0.2",
    "cross-env": "^7.0.0",
    "env-cmd": "^10.0.1",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.2",
    "husky": "^4.2.1",
    "install-peers": "^1.0.3",
    "react": "^16.12.0",
    "react-dom": "^16.12.0"
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...