Неудачный тест: Из рендеринга ничего не было возвращено. проходит идентичный тест, единственным отличием от неудачного теста является использование начальных значений

0

Вопрос

Я пытаюсь проверить, работают ли мои маршруты, первый тест проходит, когда я тестирую маршрут "/" по умолчанию, однако второй тест не проходит. разница лишь в том, что во втором тесте initialEntries={['/register']} вводится, и в результате второй тест по этой причине не проходит:

"Вход в систему(...): Из рендеринга ничего не было возвращено. Обычно это означает , что оператор return отсутствует. Или, чтобы ничего не отображать, верните значение null".

Я проверил другие вопросы, касающиеся этого, но они, похоже, не соответствуют моей конкретной проблеме

это мое app.js который содержит все маршруты

import React from 'react';
import {BrowserRouter as Router, Route, Switch} from 'react-router-dom'
import PrivateRoute from './components/PrivateRoute';
import Login from './components/LoginRegister/Login';
import Dashboard from './components/Dashboard/Dashboard';
import Register from './components/LoginRegister/Register';
import PageNotFound from './components/Pages/PageNotFound';
import Header from './components/LoginRegister/Header';
function App() {

  return (
    <Router>
      <div className="main-container">
          <div className="Route-container">
          <Header/>
              <Switch>
                <PrivateRoute exact path = '/dashboard' component = {Dashboard}></PrivateRoute> 
                <Route exact path = '/' component = {Login} />
                <Route exact path = '/test' component = {Dashboard} />
                <Route exact path = '/register' component = {Register} /> 
                <Route component = {PageNotFound} /> 
              </Switch>
          </div>
        </div>
    </Router>
  );
}

export default App; 

Это мое App.test.js

import React from 'react'
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router';
import App from "./App";
import Dashboard from './components/Dashboard/Dashboard'; 
import Header from './components/LoginRegister/Header';
import Login from './components/LoginRegister/Login';
import Register from './components/LoginRegister/Register';
import PageNotFound from './components/Pages/PageNotFound';
import '@testing-library/jest-dom/extend-expect';

jest.mock('./components/Dashboard/Dashboard');
jest.mock('./components/LoginRegister/Login');
jest.mock('./components/LoginRegister/Register');
jest.mock('./components/Pages/PageNotFound');
jest.mock('./components/LoginRegister/Header');

describe("App component", () =>{
    it("renders page header and login component on default route", ()=>{
        Header.mockImplementation(()=> <div>HeaderMock</div>);
        Login.mockImplementation(()=> <div>LoginMock</div>);

        render(
          <MemoryRouter>
            <App />
          </MemoryRouter>
        );
        
        expect(screen.getByText("HeaderMock")).toBeInTheDocument();
        expect(screen.getByText("LoginMock")).toBeInTheDocument();
    });

    it("Renders page header and Register component on Register route", ()=>{
      Header.mockImplementation(()=> <div>HeaderMock</div>);
      Register.mockImplementation(()=> <div>RegisterMock</div>);

      render(
        <MemoryRouter initialEntries={['/register']}>
            <App />
        </MemoryRouter>
      );
      
      expect(screen.getByText("HeaderMock")).toBeInTheDocument();
      expect(screen.getByText("RegisterMock")).toBeInTheDocument();
  });
});

Это тот самый Register.js компонент

import React from 'react'
import { useState } from 'react';
import { Link, useHistory } from 'react-router-dom';

const initialState = {
    credentials: {
    name: '',
    username: '',
    password: ''
  }
}

function Register() {
    const [state, setState] = useState(initialState)
    const history = useHistory()

    function goToLogin () {
        history.push('/')
    }

function handleChange(e) {
    setState({
        credentials: {
            ...state.credentials,
            [e.target.name]: e.target.value
        }
    })
   }
    return (
        <div className = "main-container">
            
            <div className = "middle-section">
                
                <div className= "login-section">
                
                    <div className = "selection login-flex-item">
                        Already a member? &nbsp;
                        <Link to ='/' className = 'select-logreg'>Login</Link>
                    </div>

                    <form className = 'login-flex-item' onSubmit = {goToLogin}>
                
                        <input className = 'form-item'
                            type = 'text'
                            name = 'name'
                            placeholder = "Enter Name"
                            value = {state.credentials.name}
                            onChange ={handleChange}
                        />
                        <input className = 'form-item'
                            type = 'text'
                            name = 'username'
                            placeholder = "Username"
                            value = {state.credentials.username}
                            onChange ={handleChange}
                        />
                        <input className = 'form-item'
                            type="password"
                            name="password"
                            placeholder = "Password"
                            value={state.credentials.password}
                            onChange={handleChange}
                        />
                        <button className = 'form-item btn'>Sign Up</button>
                    </form>
                </div>
            </div>
        </div>
    );
};

export default Register;

и это описание провала теста, которое я получаю, любая помощь была бы потрясающей, я смотрел на это в течение нескольких часов и, похоже, не могу найти решение.

 FAIL  src/App.test.js
  App component
    √ renders page header and login component on default route (33 ms)
    × Renders page header and Register component on Register route (198 ms)

  ● App component › Renders page header and Register component on Register route

    Login(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.

      35 |       Register.mockImplementation(()=> <div>RegisterMock</div>);
      36 |
    > 37 |       render(
         |       ^
      38 |         <MemoryRouter initialEntries={['/register']}>
      39 |             <App />
      40 |         </MemoryRouter>

      at reconcileChildFibers (node_modules/react-dom/cjs/react-dom.development.js:14169:23)
      at reconcileChildren (node_modules/react-dom/cjs/react-dom.development.js:16990:28)
      at mountIndeterminateComponent (node_modules/react-dom/cjs/react-dom.development.js:17890:5)
      at beginWork (node_modules/react-dom/cjs/react-dom.development.js:19049:16)
      at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:3945:14)
      at HTMLUnknownElement.callTheUserObjectsOperation (node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30)
      at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:338:25)
      at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:274:3)
      at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:221:9)
      at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:94:17)
      at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:231:34)
      at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:3994:16)
      at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:4056:31)
      at beginWork$1 (node_modules/react-dom/cjs/react-dom.development.js:23964:7)
      at performUnitOfWork (node_modules/react-dom/cjs/react-dom.development.js:22779:12)
      at workLoopSync (node_modules/react-dom/cjs/react-dom.development.js:22707:5)
      at renderRootSync (node_modules/react-dom/cjs/react-dom.development.js:22670:7)
      at performSyncWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:22293:18)
      at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom.development.js:21881:7)
      at updateContainer (node_modules/react-dom/cjs/react-dom.development.js:25482:3)
      at node_modules/react-dom/cjs/react-dom.development.js:26021:7
      at unbatchedUpdates (node_modules/react-dom/cjs/react-dom.development.js:22431:12)
      at legacyRenderSubtreeIntoContainer (node_modules/react-dom/cjs/react-dom.development.js:26020:5)
      at Object.render (node_modules/react-dom/cjs/react-dom.development.js:26103:10)
      at node_modules/@testing-library/react/dist/pure.js:101:25
      at batchedUpdates$1 (node_modules/react-dom/cjs/react-dom.development.js:22380:12)
      at act (node_modules/react-dom/cjs/react-dom-test-utils.development.js:1042:14)
      at render (node_modules/@testing-library/react/dist/pure.js:97:26)
      at Object.<anonymous> (src/App.test.js:37:7)
1

Лучший ответ

1

От доктора<Router>:

Общий низкоуровневый интерфейс для всех компонентов маршрутизатора. Обычно приложения вместо этого используют один из маршрутизаторов высокого уровня:

  • <BrowserRouter>
  • <HashRouter>
  • <MemoryRouter>
  • <NativeRouter>
  • <StaticRouter>

Проблема в том, что <BrowserRouter> компонент завернут в <MemoryRouter> подобный этому:

<MemoryRouter>
  <BrowserRouter>
    <Switch>
     ....
    </Switch>
  </BrowserRouter>
</MemoryRouter>

Это даст вам location От <BrowserRouter>, это будет:

location:  { pathname: '/', search: '', hash: '', state: undefined }

Вам следует разделить <Switch> и его дочерние элементы как самостоятельный компонент, такой как Routes:

import React from 'react';
import { BrowserRouter as Router, Route, Switch, useLocation } from 'react-router-dom';

const Login = () => <div>login</div>;
const Register = () => <div>Register</div>;

export const Routes = () => {
  const location = useLocation();
  console.log('location: ', location);
  return (
    <Switch>
      <Route exact path="/" component={Login} />
      <Route exact path="/register" component={Register} />
    </Switch>
  );
};

function App() {
  return (
    <Router>
      <Routes />
    </Router>
  );
}

export default App;

Так что вы можете использовать Routes с <MemoryRouter> для тестирования:

import React from 'react';
import { MemoryRouter } from 'react-router-dom';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { Routes } from './app';

describe('App component', () => {
  it('renders page header and login component on default route', () => {
    render(
      <MemoryRouter>
        <Routes />
      </MemoryRouter>
    );
    expect(screen.getByText('login')).toBeInTheDocument();
  });

  it('Renders page header and Register component on Register route', () => {
    render(
      <MemoryRouter initialEntries={['/register']}>
        <Routes />
      </MemoryRouter>
    );
    expect(screen.getByText('Register')).toBeInTheDocument();
  });
});

результат теста:

 PASS  examples/70090905/app.test.tsx (8.087 s)
  App component
    ✓ renders page header and login component on default route (45 ms)
    ✓ Renders page header and Register component on Register route (3 ms)

  console.log
    location:  {
      pathname: '/',
      search: '',
      hash: '',
      state: undefined,
      key: 'zlnxcn'
    }

      at Routes (examples/70090905/app.tsx:9:11)

  console.log
    location:  {
      pathname: '/register',
      search: '',
      hash: '',
      state: undefined,
      key: '8z804n'
    }

      at Routes (examples/70090905/app.tsx:9:11)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        8.625 s, estimated 11 s

В иллюстративных и демонстрационных целях я удалил ненужный код.

Версии пакетов:

"react-router-dom": "^5.2.0"
2021-11-24 07:54:05

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................