简体   繁体   English

检查是否在测试模式下调用了 function

[英]Check if a function was called in testing mode

I have this javascript code that make a get request.我有这个发出获取请求的 javascript 代码。 It works fine.它工作正常。

 export const getReq = () => { fetch( 'https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits', ).then((response) => { let status = null; if (response.status === 200) { status = response.status; } else { status = 'error'; } if (status === 200) { alert('success'); } else { alert('Error'); } return response.json(); }).then((commits) => { return commits.map(({sha}) => sha)[0]; }); };

I want to test if my function that fetch was called:我想测试我的 function 是否调用了 fetch:

 import { getReq } from './getReq'; jest.mock('./getReq', () => ({ getReq: () => 123 })); describe('success', () => { test('check if was caled', async () => { const sha = await getReq(); expect(sha).toHaveBeenCalled(); }); });

Doing this test i get the next error: Matcher error: received value must be a mock or spy function做这个测试我得到下一个错误: Matcher error: received value must be a mock or spy function
How to test if my function that make a get request was called?如何测试我的get是否被调用?

From your test, it's not entirely clear whether you know what getReq is supposed to do.从您的测试来看,您是否知道getReq应该做什么并不完全清楚。 You mock it out* to return 123 , but assuming the implementation is mostly correct it would actually return a promise of an array of strings where each string is the first character of a sha (actually it returns undefined, because you don't return the promise chain, and maybe you actually wanted it to return the complete sha of the first commit rather than the first character of the sha for every commit?)您将其模拟出来*以返回123 ,但假设实现大部分正确,它实际上会返回一个字符串数组的 promise ,其中每个字符串都是sha的第一个字符(实际上它返回未定义,因为您不返回promise 链,也许您实际上希望它返回第一次提交的完整sha而不是每次提交的sha的第一个字符?)

Similarly in your previous attempt your mock for fetch didn't make sense:同样,在您之前的尝试中,您的fetch模拟没有意义:

global.fetch = jest.fn(() => {
  return Promise.resolve(123);
});

Your code certainly doesn't expect fetch to return a promise of 123 , it expects it to return a promise of a response object with a status prop and a json method that returns a promise of an array of objects with sha props. Your code certainly doesn't expect fetch to return a promise of 123 , it expects it to return a promise of a response object with a status prop and a json method that returns a promise of an array of objects with sha props. Your test doubles need to have the same interface as the thing they're replacing, or they're pointless.您的测试替身需要与他们要替换的东西具有相同的界面,否则它们毫无意义。

Broadly, I would expect a test for this function to look like:总的来说,我希望这个 function 的测试看起来像:

import { getReq } from "./getReq";

it("works", async () => {
  global.alert = jest.fn();  // otherwise 'Error: Not implemented: window.alert'
  global.fetch = jest.fn().mockResolvedValueOnce({
    json: () => Promise.resolve([
      /* from https://developer.github.com/v3/repos/commits/#list-commits */
      { sha: "6dcb09b5b57875f334f61aebed695e2e4193db5e" },
      { sha: "f103561f390825e76f196ce952a982542861fef3" },
    ]),
    status: 200
  });

  const result = await getReq();

  expect(global.alert).toHaveBeenCalledWith("success");
  expect(global.fetch).toHaveBeenCalledWith(
    "https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits"
  );
  expect(result).toEqual(["6", "f"]); // or maybe "6dcb09b5b57875f334f61aebed695e2e4193db5e"?
});

This will currently fail on the last expectation for the reason I hint at above.由于我在上面暗示的原因,目前这将在最后一个期望上失败。

Alternatively you could split that up into three tests: makes the right request, sends the right alert, returns the right result.或者,您可以将其拆分为三个测试:发出正确的请求、发送正确的警报、返回正确的结果。 There should also be tests for the unhappy paths, eg if the request returns non-200 (should you still be assuming the response.json() will be fine in that case?)还应该对不愉快的路径进行测试,例如,如果请求返回非 200(您是否仍应假设response.json()在这种情况下会很好?)

You could also look into MSW for an approach to testing that's less tightly coupled to the fetch API (we shouldn't really be mocking what we don't own).您还可以查看MSW以寻找一种与fetch API 耦合度较低的测试方法(我们不应该真正成为我们不拥有的 mocking)。

* Your test is of a mock, there's no production code involved. *您的测试是模拟的,不涉及生产代码。 Don't mock the thing you're supposed to be testing.不要嘲笑你应该测试的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM