Apollo Client测试中点击事件触发模拟响应缺失错误求助
为什么点击事件触发后会出现Apollo Mock无响应的错误?
测试场景
测试代码如下:
describe('<UserTable />', () => { const gqlMock: Array<MockedResponse> = [ { request: { query: QUERY_USER_LIST }, result: { data: { getUserList: [ { userId: 'testuser', userName: 'testname', ... } ] } } }, { request: { query: VALIDATE_TOKEN }, result: { data: { validateAccessToken: true } } }, ] beforeEach(() => { render( <MockedProvider mock={gqlMock} addTypename={false}> <MemoryRouter> <Routes> <Route path={'/'} element={<UserTable />} /> </Routes> </MemoryRouter> </MockedProvider> ) }) it('用户显示测试', async () => { await waitFor(() => { const testuser = screen.getByText('testuser') expect(testuser).toBeInTheDocument() }) }) it('添加弹窗测试', async () => { await act(async () => { const addButton = screen.getByText('Add new user') expect(addButton).toBeInTheDocument() await userEvent.click(addButton) }) await waitFor(() => { const popupTitle = screen.getByText(/This dialog/i) expect(popupTitle).toBeInTheDocument() }) }) })
错误信息
第一个测试用例执行正常,但第二个测试用例触发如下错误:
No more mocked responses for the query: query validateAccessToken { validateAccessToken } Expected variables: {} This typically indicates a configuration error in your mocks setup, usually due to a typo or mismatched variable.
背景
系统会在每次请求时通过async-await校验JWT Token,校验完成后再执行后续操作。
问题原因
问题出在Apollo MockedProvider的Mock规则和业务逻辑的匹配上:
- 每个测试用例执行时,组件初始化会先触发一次
VALIDATE_TOKEN请求,消耗掉Mock数组中对应的响应; - 点击“添加用户”按钮后,触发的添加操作会再次发起
VALIDATE_TOKEN请求(符合“每次请求都校验Token”的逻辑); - 你定义的
gqlMock中,VALIDATE_TOKEN的Mock响应只配置了1次,第二次请求时没有可用的Mock,因此抛出错误。
第一个测试用例只触发了一次VALIDATE_TOKEN(组件初始化时),Mock数量足够,所以不会报错。
解决方案
你有两种可行的解决方式:
方式1:给Mock响应添加times属性,允许多次匹配
修改VALIDATE_TOKEN的Mock配置,添加times属性指定可匹配次数,比如设置为无限次:
{ request: { query: VALIDATE_TOKEN }, result: { data: { validateAccessToken: true } }, times: Infinity // 允许无限次匹配,也可设置为具体次数如2 }
方式2:在Mock数组中添加多个相同的VALIDATE_TOKEN响应
如果不想使用times属性,直接在gqlMock中重复添加VALIDATE_TOKEN的Mock,保证每个请求都有对应的响应:
const gqlMock: Array<MockedResponse> = [ { /* QUERY_USER_LIST 的 Mock */ }, { /* VALIDATE_TOKEN 的 Mock */ }, { request: { query: VALIDATE_TOKEN }, result: { data: { validateAccessToken: true } } }, ]
内容的提问来源于stack exchange,提问作者Prunus Nira
相关产品推荐
相关产品推荐

