通过 jest mock 测试 catch 块
Posted
技术标签:
【中文标题】通过 jest mock 测试 catch 块【英文标题】:Testing catch block via jest mock 【发布时间】:2017-07-15 08:07:01 【问题描述】:我正在尝试通过 jest 测试异步 redux 操作的“catch”块,但是在模拟中抛出一个 catch 会导致整个测试失败。
我的操作如下:
export function loginUser(username, password)
return async dispatch =>
dispatch(type: UPDATE_IN_PROGRESS);
try
let response = await MyRequest.postAsync(
'/login', username: username, password: password
);
dispatch(
type: USER_AUTHENTICATED,
username: response.username,
token: response.token,
role: response.role,
id: response.id
);
catch (error)
dispatch(type: USER_SIGNED_OUT);
throw error;
finally
dispatch(type: UPDATE_COMPLETE);
;
测试试图模拟“MyRequest.postAsync”以引发错误并因此触发 catch 块,但测试只是退出并显示“失败”消息
it('calls expected actions when failed log in', async() =>
MyRequest.postAsync = jest.fn(() =>
throw 'error';
);
let expectedActions = [
type: UPDATE_IN_PROGRESS,
type: USER_SIGNED_OUT,
type: UPDATE_COMPLETE
];
await store.dispatch(userActions.loginUser('foo', 'bar'));
expect(store.getActions()).toEqual(expectedActions);
);
有没有办法通过一个笑话模拟函数(或任何其他方式)触发 catch 块在我的测试中执行?无法测试大量代码会很烦人(因为我所有的请求都以相同的方式工作)。
在此先感谢您的帮助。
【问题讨论】:
给你用jest.mock
模拟MyRequest
,否则不行
对不起@AndreasKöberle 你能稍微详细说明一下吗?使用 jest.fn() 似乎可以很好地模拟导入模块上的函数,这是导致问题的throw 'error'
可能是catch
块中的throw
【参考方案1】:
我将我们将在测试函数中访问的实例变量设置为未定义,以便它将进入 catch 块。
PS : 这可能不可能一直存在,因为我们可能不会一直有变量
class APIStore
async fetchProductsAPI()
try
const products = networkManager.fetch('products')
this.productsStore.setProducts(prodcuts)
catch(e)
this.apiStatus = API_FAILED
this.apiError = e
测试用例
it('Check API Error ', async () =>
const toCheckErrorStore = new APIStore()
// Setting products store to undefined so that execution goes to catch block
toCheckErrorStore.productsStore = undefined
await toCheckErrorStore.fetchProductsAPI()
expect(toCheckErrorStore.apiStatus).toBe(API_FAILED)
expect(toCheckErrorStore.apiError).toEqual(errorObjectIWantToCompareWith)
【讨论】:
【参考方案2】:我不知道它是否仍然相关,但你可以这样做:
it('tests error with async/await', async () =>
expect.assertions(1);
try
await store.dispatch(userActions.loginUser('foo', 'bar'));
catch (e)
expect(e).toEqual(
error: 'error',
);
);
这是一个关于错误处理的documentation
【讨论】:
【参考方案3】:我有同样的问题。对我来说,以下工作。用try/catch
结束等待
it('calls expected actions when failed log in', async() =>
MyRequest.postAsync = jest.fn(() =>
throw 'error';
);
let expectedActions = [
type: UPDATE_IN_PROGRESS,
type: USER_SIGNED_OUT,
type: UPDATE_COMPLETE
];
try
await store.dispatch(userActions.loginUser('foo', 'bar'));
catch(e)
expect(store.getActions()).toEqual(expectedActions);
);
【讨论】:
以上是关于通过 jest mock 测试 catch 块的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 jest 在 javascript 中测试 try catch 代码并在 express 中包含带有中间件的 next() 调用?
「CI集成」基于Jest Mock API对业务逻辑集成测试附源码
如何使用 jest.mock 模拟 useRef 和反应测试库