Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/422.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我该如何模仿两次回访或一次承诺一次回访?_Javascript_Reactjs_Jestjs_Fetch Api - Fatal编程技术网

Javascript 我该如何模仿两次回访或一次承诺一次回访?

Javascript 我该如何模仿两次回访或一次承诺一次回访?,javascript,reactjs,jestjs,fetch-api,Javascript,Reactjs,Jestjs,Fetch Api,我正在尝试测试loadAllProjects函数 测试在.then()处失败,错误为:TypeError:无法读取未定义的属性“then” 我还尝试用token()模拟GetHeaders的响应,但无法使其正常工作 我在这一点上打了个台球,非常感谢您的帮助 测试: 代码: 测试中使用的存储: const store = mockStore(Map( { allProjects: Map({ }), c

我正在尝试测试loadAllProjects函数

测试在.then()处失败,错误为:TypeError:无法读取未定义的属性“then”

我还尝试用token()模拟GetHeaders的响应,但无法使其正常工作

我在这一点上打了个台球,非常感谢您的帮助

测试:

代码:

测试中使用的存储:

    const store = mockStore(Map(
        {
            allProjects: Map({
            }),
            currentProject: Map({

                authenticationData: Map({

                })
            })
        })

    );

您使用什么Redux中间件来实现异步?确保在创建用于测试的存储时设置了中间件

因为我没有看到上面代码中的任何地方,所以我假设我们这里没有使用中间件

由于loadAllProjects是一个高阶函数,我会这样做:

it('should create SET_ALL_PROJECTS action when fetching projects', (done) => {
    fetch
        .once(JSON.stringify([{ access_token: "12345" }]))
        .once(JSON.stringify({ name: "x" }))

    const expectedActions = [
        { type: "SET_ALL_PROJECTS", json: { name: "x" } },
    ]

    // Higher order function that returns a new function.
    const loadAllProjectsAsync = actions.loadAllProjects();

    // The function returned expects a dispatch from Redux as an argument.
    // It will do async work and when its done, it will call the provided dispatch.
    loadAllProjectsAsync(store.dispatch).then(() => {
       expect(store.getActions()).toEqual(expectedActions);
       done();
    })

});
您还需要修改LoadAllProject的代码,以便内部函数返回承诺:

export const loadAllProjects = () => {
return (dispatch) => {

    // You will need to return the promise in order for the test to be able to call .then() on it.
    return getHeadersWithToken()
        .then(applicationJsonHeaders => {
            const requestOptions = {
                method: 'GET',
                headers: applicationJsonHeaders,
            };
            return fetch(process.env.REACT_APP_PROJECTS_API_URL + "/projects", requestOptions)
                .then(parseResponseAndHandleErrors)
                .then(json => {
                    dispatch(setAllProjects(json))})
                .catch(error => {
                    console.error(error)
                    dispatch(failedToLoadProjects(error))
                });
        })
}}
另外,如前所述,如果您正在测试异步内容,那么必须在测试完成时告诉jest。为此,让您的it调用将
done
作为参数,并在验证结果i之后将其作为函数调用。然后()

这只是我这边的一个快速修复。上面的代码中可能仍然有我遗漏的东西或一些bug,但是你明白了


如果您有任何后续问题,请告诉我?

如果这对任何人都有用,并且为了感谢Septstium的回答,我最终将代码更改为:

async getHeadersWithToken(requestType) {
    if (process.env.REACT_APP_RUNNING_LOCALLY==="true") {
        return {
            'Accept': 'application/json, text/plain, */*',
            'Content-Type': 'application/json'
        };
    }
    let result = await fetch("/.auth/me", this.requestOptions)
    let headers = result.json()
        .then( json => {
            const header = 'Bearer ' + json[0].access_token
            const applicationJsonHeaders = this.getJsonHeaders(header, requestType)
            return applicationJsonHeaders
        })
        .catch(error => {
            console.error(error)
        })
    return headers
}


测试的目的是:

const checkActionsWereDispatched = async (expectedActions, actionCreator) => {
    const store = mockStore(Map(
        {
        }),
    );
    store.dispatch(await actionCreator.apply()).then(() => {
        expect(store.getActions()).toEqual(expectedActions)
    })
}

it('should create SET_ALL_PROJECTS action when fetching projects', async () => {
    fetch
        .once(JSON.stringify([{ access_token: "12345" }]))
        .once(JSON.stringify({ name: "x" }))
    const expectedActions = [
        { type: "SET_ALL_PROJECTS", json: { name: "x" } },
    ]
    checkActionsWereDispatched(expectedActions, actions.loadAllProjects)
});

如上所述,我认为Spetastium的测试版本比我的更容易阅读,他的文章非常有用。

哪个
then()
?store.dispatch(actions.loadAllProjects.apply())。那么
store
是从哪里导入的呢?我将该存储添加到了问题中。虽然如此,我还是有点惊讶于它能起作用,您不需要向
it
提供
done
回调,以便它知道测试已完成吗?请参阅。感谢您抽出时间回复。最后,我更改了代码本身(见下一篇文章)。我更喜欢你的测试版本,因为它更可读。没问题。希望它对您有效,并且您对代码D感到满意
async getHeadersWithToken(requestType) {
    if (process.env.REACT_APP_RUNNING_LOCALLY==="true") {
        return {
            'Accept': 'application/json, text/plain, */*',
            'Content-Type': 'application/json'
        };
    }
    let result = await fetch("/.auth/me", this.requestOptions)
    let headers = result.json()
        .then( json => {
            const header = 'Bearer ' + json[0].access_token
            const applicationJsonHeaders = this.getJsonHeaders(header, requestType)
            return applicationJsonHeaders
        })
        .catch(error => {
            console.error(error)
        })
    return headers
}
export const loadAllProjects = () => {
    return async dispatch => {
        const authenticator = new Authenticator()
        let applicationJsonHeaders = await authenticator.getHeadersWithToken(constants.GET)
        let loggedInUser = await authenticator.getLoggedInUser()
        const requestOptions = {
            method: 'GET',
            headers: applicationJsonHeaders,
        };
        return await fetch(process.env.REACT_APP_PROJECTS_API_URL + "/projects", requestOptions)
            .then(response => {
                return parseResponseAndHandleErrors(response)
            })
            .then(json => dispatch(setAllProjects(json)))
            .then(()=> dispatch(setAuthenticationData(loggedInUser)))
            .catch(error => {
                console.error(error)
                return dispatch(failedToLoadProjects(error))
            });
    }
} 
const checkActionsWereDispatched = async (expectedActions, actionCreator) => {
    const store = mockStore(Map(
        {
        }),
    );
    store.dispatch(await actionCreator.apply()).then(() => {
        expect(store.getActions()).toEqual(expectedActions)
    })
}

it('should create SET_ALL_PROJECTS action when fetching projects', async () => {
    fetch
        .once(JSON.stringify([{ access_token: "12345" }]))
        .once(JSON.stringify({ name: "x" }))
    const expectedActions = [
        { type: "SET_ALL_PROJECTS", json: { name: "x" } },
    ]
    checkActionsWereDispatched(expectedActions, actions.loadAllProjects)
});