TypeError:中间件不是函数。 Reddit-clone 应用程序,使用异步和等待从 api 获取

问题描述 投票:0回答:1

我正在测试我的 Reddit 克隆应用程序,但我似乎无法找到解决此问题的方法。我尝试了 yt 视频中的解决方案,但没有任何帮助,我也按照文档中有关此主题的说明进行操作。我的应用程序是使用 redux-toolkit 制作的。谢谢

下面的代码是我的测试文件

import React from 'react'
import { render,screen } from '@testing-library/react'
import configureStore from 'redux-mock-store'
import { Provider } from 'react-redux'
import Comments from '../Comments'
import { MemoryRouter } from 'react-router-dom'
import thunk from 'redux-thunk'
const middleware = [thunk]
const mockStore = configureStore(middleware)


const initialState = {
    comments: {
        comments: {
                data: {
                    children: [
                        {data: {id: 1, body: 'comment 1', author: 'author 1'}},
                        {data: {id: 2, body: 'comment 2', author: 'author 2'}}
                    ]
                },
        },
        selectedComments: 'selected comment',
        showButton: 'hide comments'
    }
}

test('should render the comment count in comment component', () => {
    var storeE = mockStore(initialState)
        render(  
            <Provider store={storeE}>
                <MemoryRouter>
                    <Comments/>   
                </MemoryRouter>
            </Provider>
        )
    const commentCount = screen.getByText('comment 1')

    expect(commentCount('2 comments')).toBeVisible();

})

下面的代码是我的评论组件

import { Box, Typography, Button } from '@mui/material'
import React, { useEffect, useRef } from 'react'
import { Link } from 'react-router-dom'
import {useDispatch, useSelector} from 'react-redux'
import { getCommentsData } from '../API/Api'
import { setButton } from './CommentsSlice'
const Comments = () => {
    const dispatch = useDispatch()
    const commentsData = useSelector(state => state.comments.comments?.data?.children)
    const selectedComment = useSelector(state => state.comments.selectedComments)

    const selectedBtn = useSelector(state => state.comments.showButton)
    const commentsList = useRef()

    
    useEffect(() => {
        dispatch(getCommentsData(selectedComment))
        window.scrollTo({
            top: 0,
            behavior: 'smooth'
        })
    }, [dispatch, selectedComment])

    const hideComment = () => {
        if(selectedBtn === 'show comments'){
            dispatch(setButton('hide comments'))
        }
        if(selectedBtn === 'hide comments'){
            dispatch(setButton('show comments'))
        }
    }

    const commentItems = commentsData && commentsData.length > 0 ? (
        commentsData.map((item, idx) => (
            <Box key={item.data.id}
                sx={{color: 'white', 
                display:'flex', 
                justifyContent: 'center', 
                alignItems:'center', 
                flexDirection: 'column',
                borderBottom: '1px solid #3d3d3d',
                marginX: '70px',
                marginBottom:'50px'}}>
                    <Typography gutterBottom>Comment {idx + 1}</Typography>
                    <Box sx={{marginTop:'20px',marginBottom:'20px', textAlign:'center'}}>
                        <Typography>{item.data.body}</Typography>
                        <Typography sx={{marginTop:'10px'}}>Author: {item.data.author}</Typography>
                    </Box>
            </Box>
        ))
    ):(<Box>No Comments</Box>)


  return (
    <Box sx={{width: '100%', marginTop:'20px', marginLeft:'20px'}}>
        <Box>
            <Link to='/' onClick={hideComment}>
                <Button>Back to posts</Button>
            </Link>
        </Box>

        <Box ref={commentsList}>
            {commentItems}
        </Box>
    </Box>
  )
}

export default Comments

下面的代码是我的评论Slice

import { createSlice } from "@reduxjs/toolkit";

export const CommentsSLice = createSlice({
    name: 'comments',
    initialState: {
        comments: [],
        selectedComments: '',
        showButton: 'show comments'
    },
    reducers:{
        setComments(state, action){
            state.comments = action.payload
        },
        setSelectedComment(state, action){
            state.selectedComments = action.payload
        },
        setButton(action, state){
            state.showButton = action.payload
        }
    }
})

export const {
    setComments,
    setSelectedComment,
    setButton
} = CommentsSLice.actions

export default CommentsSLice.reducer

我尝试在商店文件中制作自定义中间件,几乎每个人都表明可以解决这个问题。在 redux 工具包的文档中,它说了同样的事情来更改中间件,就像他们说的那样,仍然是同样的错误。我从 Jest 测试更改为 Vitest,并更改了设置以使其工作,但仍然没有任何效果。

javascript unit-testing react-redux redux-toolkit
1个回答
0
投票

redux-mock-store
已经过时了。在单元测试中创建真正的 Redux 存储是常见的建议和实践。 Redux-Toolkit 创建的商店已集成并默认启用 Thunk 中间件。

示例:

import React from 'react';
import { render, screen } from '@testing-library/react';
import { configureStore } from "@reduxjs/toolkit"; // <-- create real store
import { Provider } from 'react-redux';
import { MemoryRouter } from 'react-router-dom';
import reducer from '../path/to/rootReducer'; // <-- import reducer
import Comments from '../Comments';

const preloadedState = {
  comments: {
    comments: {
      data: {
        children: [
          { data: { id: 1, body: 'comment 1', author: 'author 1' } },
          { data: { id: 2, body: 'comment 2', author: 'author 2' } }
        ]
      },
    },
    selectedComments: 'selected comment',
    showButton: 'hide comments'
  }
};

const Providers = ({ children }) => (
  <Provider store={store}>
    <MemoryRouter>
      {children}
    </MemoryRouter>
  </Provider>
);

test('should render the comment count in comment component', () => {
  const store = configureStore({
    preloadedState,
    reducer,
  });

  render(<Comments />, { wrapper: Providers });

  const commentCount = screen.getByText('comment 1');

  expect(commentCount('2 comments')).toBeVisible();
});

请参阅 Redux Writing Tests 文档,了解更多一般测试信息和策略。

© www.soinside.com 2019 - 2024. All rights reserved.