模拟 Axios 以测试 .catch()
Posted
技术标签:
【中文标题】模拟 Axios 以测试 .catch()【英文标题】:Mock Axios to test .catch() 【发布时间】:2020-03-03 23:37:57 【问题描述】:我一直在尝试编写测试来测试 axios 调用,但现在需要测试 catch
部分。
我已经能够通过像这样模拟 axios 来做到这一点,但似乎无法获得测试 catch 的方法。我从堆栈溢出和网络中跟踪了许多不同的示例。
jest.mock('axios', () => jest.fn(() => Promise.resolve( data: mockData )));
但这总是会返回一个好的结果,所以不能测试捕获。我要测试的代码是:goToUrl()
只是一个window.location.assign(url)
,但已导入。
fetchBundlesFromApi(params)
.then(( data: bundles ) =>
updateBundles(bundles);
this.setState( showUpdatingPrices: false );
)
.catch(() => goToUrl(bundlesUrl));
在我对.then()
部分的测试中,我这样做:
const fetchedBundles = await fetchBundlesFromApi(
'?params',
);
expect(fetchedBundles.data).toEqual(mockData);
但是,如果我按照 Mocking Axios with Jest in React - mock function not being called 这样的示例进行操作,我无法手动模拟 get
如果我将模拟 axios 文件放在文件夹 __mocks__
中,那么很多测试套件都失败了,所以我只想模拟它在这个测试文件中。
这是我尝试做的一个例子:
jest.mock('axios', () => (
get: () => jest.fn(() => Promise.resolve( data: mockData )),
default: () => jest.fn(() => Promise.resolve( data: mockData )),
));
但是TypeError: (0 , _axios.default) is not a function
的测试错误
编辑:
这是我的 fetchBundlesApi 函数:
const fetchBundlesFromApi = params => axios(`$bundleRoute/bundles$params`);
编辑:捕捉测试
it('should redirect if api fails', async () =>
const networkError = new Error('Some network error');
axios.mockRejectedValueOnce(networkError);
const goToUrl = jest.fn();
let error;
try
await fetchBundlesFromApi('?params');
catch (err)
error = err;
expect(error).toEqual(networkError);
expect(goToUrl).toHaveBeenCalled();
);
在我的组件中,我像这样导入goToUrl
:
import goToUrl from 'Helpers';
【问题讨论】:
你试过Promise.reject
而不是Promise.resolve
吗?
我没有尝试过,因为如果我这样做,那么我当前的测试将失败
【参考方案1】:
您可以利用 Jests 功能在它们运行后弹出实现,即mockImplementationOnce 和朋友。
import axios from 'axios';
jest.mock('axios');
// default implementation
axios.get.mockResolvedValue(mockedData);
describe('#fetchBundlesFromApi', () =>
it('returns data from API', async () =>
const fetchedBundles = await fetchBundlesFromApi('?params');
expect(fetchedBundles.data).toEqual(mockData);
);
it('redirects on failure', () =>
// override behaviour for this one call
axios.get.mockRejectedValueOnce();
// verify your failure test
);
);
【讨论】:
嘿,我试过了,但我得到一个错误说`TypeError:无法读取未定义的属性'then''我尝试将解析的值更改为promise,但仍然是同样的问题。我刚刚用我的 fetch 函数更新了我的问题,所以你可以看到它在做什么 @saunders 所以看起来你没有调用任何显式函数,即get
,你似乎只是依赖于 axios 的默认行为。您可以将模拟更改为axios.mockResolvedValue(...)
,也可以将代码更改为更明确的axios.get('...:)
感谢您为这条好路工作,但我刚刚尝试了 catch 部分,它似乎可以解决我的 mockData。 axios.mockRejectedValueOnce(Promise.reject(new Error('something bad happened')));
但在测试中它说它收到了mockData
数组
我已经尝试了很多不同的东西,但我似乎无法调用 goToUrl()
它一直在说 Expected mock function to have been called, but it was not called
我已经编辑了我的问题以包含我拥有的代码,但它不是很有效跨度>
@saunders没问题,让我看看以上是关于模拟 Axios 以测试 .catch()的主要内容,如果未能解决你的问题,请参考以下文章