在 moxios 拒绝时不调用 catch

catch is not invoked on moxios reject

我正在尝试使用 moxios 和 jest 测试对我的一个 axios 请求调用的拒绝。调用方法(调用 axios.get)抛出错误但未调用 catch 块。

我的测试代码片段如下所示,

it('should call errorHandler method when request is rejected', done => {
        const errorResp = {
            status: 400,
            response: {message: 'invalid data'}
        };
        let mockFunction = jest.fn();
        Axios.getRaw('/test').then(mockFunction);
        moxios.wait(async () => {
            let req = moxios.requests.mostRecent();
            try {
                let rejection = await req.reject(errorResp);
                console.log('rejection', rejection);// rejection is undefined
                done();
            } catch (e) {
                console.log(e);
                // test assertions
                done(e);
            }

        })
    });

getRaw 方法,

const API_WRAPPER = TryCatchHandler.genericTryCatch;

export default {
  getRaw: path => API_WRAPPER(axios.get(`${SERVER_DOMAIN}${path}`)),
}

API_WRAPPER方法,

export default {
    genericTryCatch: async (executionMethod) => {
        try {
            const response = await executionMethod;
            return response;
        } catch (error) {
            return ApiError.errorHandler(error);
        }
    }
}

errorHandler 方法,

export default {
    errorHandler: error => {
        const {status} = error;
        switch (status) {
            case 400:
            case 401:
            case 403:
            case 404:
            case 409:
            case 417:
            case 500:
            case 502:
                console.log("Error Handler says:", error);
                return error.response.data;
            default:
                console.log("Error Handler says:", error);
                let errorObj = {
                    errorMsg: error.message,
                    stack: error.stack
                };
                return errorObj;
        }
    }
}

由于未调用 catch 块,我无法断言我的测试用例。 如何调用捕获?

关于您提供的代码,有两点需要指出。

首先,你应该考虑到所有用Axios.getRaw发出的请求都被API_WRAPPER包装了。在请求导致错误的情况下,API_WRAPPER 是 return 处理错误的结果(通过 errorHandler 方法)。 因此,调用 Axios.getRaw 将永远不会执行调用中存在的任何 catch 语句:

Axios.getRaw('/test').then(function() {
    // The code inside this method will always be executed, even when the request fails.
}).catch(function() {
    // The code inside this method will never be executed.
});

在出现 400 错误(您在测试中测试的错误)的情况下,errorHandler 方法是 returning error.response.data 的值。但是在您的测试中,您创建的错误没有 data 属性:

const errorResp = {
    status: 400,
    response: {message: 'invalid data'}
};

因此,为了在测试中获得一些有意义的数据,您应该添加具有某些值的 data 属性。

第二位,我认为你没有正确使用moxios库。您正在获取最新的请求,然后您正在等待拒绝的结果:

let rejection = await req.reject(errorResp);
console.log('rejection', rejection);// rejection is undefined

但是调用 req.reject 并没有 return 承诺(事实上,它没有 return 任何东西,这就是为什么你在 console.log语句)。您应该等待您最初的 Axios.getRaw 承诺得到解决。

记住这一点你可以像这样重写你的测试:

it('should call errorHandler method when request is rejected', function(done) {
    const errorResp = {
        status: 400,
        response: { message: 'invalid data', data: 'invalid data' }
    };

    // Store the promise so that we can wait for it to finish once we call the moxios reject method.
    const promise = Axios.getRaw('/test');

    moxios.wait(async function() {
        let req = moxios.requests.mostRecent();
        req.reject(errorResp);

        // As your code does not generate an error in a 400 failed request, we use the then method.
        promise.then(function(err) {
            // In a 400 error, the err.response.data is returned as the response.
            expect(err).toBe('invalid data');
            done();
        });
    });
});

希望对您有所帮助!