Javascript 如何用不同的返回值模拟在不同组件中调用的相同函数

Javascript 如何用不同的返回值模拟在不同组件中调用的相同函数,javascript,reactjs,mocking,jestjs,Javascript,Reactjs,Mocking,Jestjs,我需要模拟一个函数useAxios,但它在两个不同的组件中调用,其中一个组件在另一个组件中使用。这是我的代码: import React,{useffect,useState}来自“React” 从“axios挂钩”导入useAxios 从“antd”导入{Table,Space} 从“@fortawesome/react fontawesome”导入{FontAwesomeIcon} 从“@fortawesome/free solid svg icons”导入{faEdit、faCalenda

我需要模拟一个函数
useAxios
,但它在两个不同的组件中调用,其中一个组件在另一个组件中使用。这是我的代码:

import React,{useffect,useState}来自“React”
从“axios挂钩”导入useAxios
从“antd”导入{Table,Space}
从“@fortawesome/react fontawesome”导入{FontAwesomeIcon}
从“@fortawesome/free solid svg icons”导入{faEdit、faCalendar、fauser plus、faTimes}
export const RemoveProjectButton=({project,updateProjects})=>{
const[,execute]=useAxios(
{
url:`${process.env.REACT\u APP\u API\u url}/projects/${project.key}/`,
方法:“删除”
},
{
手册:正确
}
)
const removeProject=异步(项目)=>{
等待执行()
更新项目(项目)
}
返回{removeProject(project)}}>
}
导出常量项目=()=>{
const[projects,setProjects]=useState([])
常量[{data,loading,error}]=useAxios(
`${process.env.REACT\u APP\u API\u URL}/projects/`
)
useffect(()=>{
setProjects(数据)
},[数据])
useEffect(()=>{},[项目])
const updateProjects=(projectToDelete)=>{
setProjects(()=>projects.filter(project=>project.key!==projectToDelete.key))
}
如果(加载)返回加载

if(error)返回

错误

常量列=[ { 标题:“标题”, 数据索引:“标题”, 关键字:“标题”, 呈现:title=>{title} }, { 标题:“开始日期”, 数据索引:“开始日期”, 键:“开始日期” }, { 标题:“说明”, 数据索引:“说明”, 关键字:“说明”, render:description=>`${description.substring(0,50)}` }, { 标题:“团队”, 数据索引:“团队”, 关键:“团队” }, { 标题:“行动”, 关键:“行动”, 呈现:(文本、记录、索引)=>( ) } ] 返回( ) }
这是我的测试:

从“React”导入React
从'@testing library/react'导入{render,cleanup,firevent}
从“../Projects”导入{Projects,RemoveProjectButton}
从“axios挂钩”导入useAxios
笑话:mock('axios-hooks')
const TABLE_TEST_ID='project TABLE'
常量伪造数据=[
{
重点:1,,
标题:“测试项目Alpha”,
起始日期:“2020-04-18”,
描述:'这只是为了测试',
团队:“A,B,C”
},
{
重点:二,,
标题:“测试项目测试版”,
起始日期:“2020-04-19”,
描述:'这也只是为了测试',
团队:“X,Y,Z”
}
]
描述('项目表',()=>{
让项目
在每个之前(()=>{
projects=JSON.parse(JSON.stringify(fakeData))
useAxios.mockReturnValue([{
数据:项目,
加载:false,
错误:null
}])
})
它('单击第行的X按钮时删除项目',异步()=>{
常量{getByTestId,queryByTestId}=render()
const executeMock=jest.fn()
useAxios.mockReturnValue([{
数据:项目,
加载:false,
错误:null
}])
.mockReturnValue([{},executeMock])
.mockReturnValue([{},executeMock])
expect(getByTestId(TABLE_TEST_ID)).toHaveTextContent('testingprojectalpha'))
等待fireEvent。单击(getByTestId('project-1'))
expect(queryByTestId('project-1')).toBeNull()
expect(getByTestId(TABLE_TEST_ID)).not.toHaveTextContent('testingprojectalpha'))
})
})
但是,我得到以下错误:

TypeError: execute is not a function

      16 |   )
      17 |   const removeProject = async (project) => {
    > 18 |     await execute()
         |           ^
      19 |     updateProjects(project)
      20 |   }
      21 |
我知道问题在于我没有为组件
RemoveProjectButton
传递正确的模拟。但是,我不知道如何实现这一点,因为在不同的组件中调用了
useAxios
,它应该具有不同的返回值。我也尝试过使用
mockImplementationOnce
,但似乎组件
项目
在呈现组件
RemoveProjectButton
之前呈现了好几次,因此,我觉得我就像在猜测我必须使用
mockImplementationOnce

的次数,然后您可以根据参数返回不同的值

useAxios.mockImplementation((…args)=>{
如果(匹配1(参数)){
返回结果1;
}
如果(匹配2(参数)){
返回结果2;
}
返回结果3;
});

我采用了@Mirone的答案所建议的方法,但在模拟问题解决后,我遇到了另一个问题,因此我将添加我的完整答案,以防其他人遇到同样的问题:

it('单击X'时删除表中的项目',async()=>{
const executeMock=jest.fn()
useAxios.mockImplementation((…args)=>{
//这种嘲弄是从米隆的回答中得到启发的
开关(参数长度){
案例1:
返回[{
数据:项目,
加载:false,
错误:null
}]
案例2:
返回[{},executeMock]
默认值:中断
}
})
const{getByTestId,findByTestId}=render()
expect(getByTestId('project-table')).toHaveTextContent('testingprojectalpha'))
fireEvent.click(getByTestId('project-1'))
const table=await findByTestId('project-table')
expect(table).not.toHaveTextContent('testingprojectalpha'))
})
模拟问题解决后,我遇到了一个错误:

警告:测试内项目的更新未包装在act(…)中

通过添加以下内容解决了此问题:

const table=await findByTestId('project-table'))
前一行一直在等待,直到重新呈现带有
data testid=“project table”
的元素,但我又遇到了一个错误:

MutationObserver不是构造函数

我发现这提供了解决方案。简而言之,公共关系
"scripts": {
   ...
   "test": "react-scripts test --env=jest-environment-jsdom-sixteen",
   ...
}