开玩笑嘲笑 toHaveReturnedWith undefined

发布于 2025-01-16 20:59:09 字数 1636 浏览 0 评论 0原文

我正在学习用笑话尤其是模拟模块进行单元测试。我在 math.js 文件中使用一些数学方法编写了一些简单的模块:

const add      = (a, b) => a + b;
const subtract = (a, b) => b - a;
const multiply = (a, b) => a * b;
const divide   = (a, b) => b / a;

module.exports = {
    add,
    subtract,
    multiply,
    divide
}

然后我将其包含在我的主 js 中,并像这样进行模块模拟:

jest.mock('./math.js');
const math = require('./math');

test("calls math.add", () => {
    math.add(1, 2);

    console.log(math.add.mock);

    expect(math.add).toHaveBeenCalled();
    expect(math.add).toHaveBeenCalledWith(1, 2);
    expect(math.add).toHaveReturned();
    expect(math.add).toHaveReturnedWith(3);
});

现在,当我运行测试时,除了最后一个测试之外,所有测试都通过了:

expect(math.add).toHaveReturnedWith(3);

在控制台中我看到:

● 调用 math.add

expect(jest.fn()).toHaveReturnedWith(expected)

Expected: 3
Received: undefined

Number of returns: 1

  10 |     expect(math.add).toHaveBeenCalledWith(1, 2);
  11 |     expect(math.add).toHaveReturned();
> 12 |     expect(math.add).toHaveReturnedWith(3);
     |                      ^
  13 | });

和 console.log(math.add.mock) 给我这个:

 console.log
      {
        calls: [ [ 1, 2 ] ],
        instances: [
          {
            add: [Function],
            subtract: [Function],
            multiply: [Function],
            divide: [Function]
          }
        ],
        invocationCallOrder: [ 1 ],
        results: [ { type: 'return', value: undefined } ],
        lastCall: [ 1, 2 ]
      }

所以看来 math.add 模拟函数不返回任何值。我的问题是为什么?我做错了什么?

I'm learning unit testing with jest and particularly mocking modules. I wrote some simple module in math.js file with some math methods:

const add      = (a, b) => a + b;
const subtract = (a, b) => b - a;
const multiply = (a, b) => a * b;
const divide   = (a, b) => b / a;

module.exports = {
    add,
    subtract,
    multiply,
    divide
}

Then I include it in my main js and I do module mocking like this:

jest.mock('./math.js');
const math = require('./math');

test("calls math.add", () => {
    math.add(1, 2);

    console.log(math.add.mock);

    expect(math.add).toHaveBeenCalled();
    expect(math.add).toHaveBeenCalledWith(1, 2);
    expect(math.add).toHaveReturned();
    expect(math.add).toHaveReturnedWith(3);
});

Now when I run my test all tests are passing besides the last one:

expect(math.add).toHaveReturnedWith(3);

In console I see:

● calls math.add

expect(jest.fn()).toHaveReturnedWith(expected)

Expected: 3
Received: undefined

Number of returns: 1

  10 |     expect(math.add).toHaveBeenCalledWith(1, 2);
  11 |     expect(math.add).toHaveReturned();
> 12 |     expect(math.add).toHaveReturnedWith(3);
     |                      ^
  13 | });

and console.log(math.add.mock) gives me this:

 console.log
      {
        calls: [ [ 1, 2 ] ],
        instances: [
          {
            add: [Function],
            subtract: [Function],
            multiply: [Function],
            divide: [Function]
          }
        ],
        invocationCallOrder: [ 1 ],
        results: [ { type: 'return', value: undefined } ],
        lastCall: [ 1, 2 ]
      }

So it seems that math.add mocked function does not return any value. My question is why? What I do wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陌上青苔 2025-01-23 20:59:09

使用 jest.mock('someModule') 后,jest 将为该模块创建一个自动模拟版本。这意味着从该模块导出的东西都被模拟了。

您可以认为模拟的 math.add 方法是 jest.fn()。它没有模拟实现。如果没有给出实现,则模拟函数在调用时将返回undefined。这就是 math.add(1, 2) 返回 undefined 的原因。

您正在测试 math 模块,那么您不应该模拟它。但如果你坚持要做的话。您可以在调用 math.add(1,2) 之前使用 math.add.mockReturnValue(3);。但这没有意义,你可以给任何你想要的值。您没有测试真正的 math.add 方法。您只需将模拟返回值与断言 expect(math.add).toHaveReturnedWith(3)

例如
math.js

const add = (a, b) => a + b;
const subtract = (a, b) => b - a;
const multiply = (a, b) => a * b;
const divide = (a, b) => b / a;

module.exports = {
  add,
  subtract,
  multiply,
  divide,
};

math.test.js

const math = require('./math');

jest.mock('./math.js');

test('calls math.add', () => {
  math.add.mockReturnValue(3);
  math.add(1, 2);

  expect(jest.isMockFunction(math.add)).toBeTruthy();

  expect(math.add).toHaveBeenCalled();
  expect(math.add).toHaveBeenCalledWith(1, 2);
  expect(math.add).toHaveReturned();
  expect(math.add).toHaveReturnedWith(3);
});

测试结果:

 PASS  stackoverflow/71605818/math.test.js
  ✓ calls math.add (3 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |      20 |     100 |                   
 math.js  |     100 |      100 |      20 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.225 s

After using jest.mock('someModule'), jest will create an auto-mocked version for this module. This means the exported things from this module are all mocked.

You can think that the mocked math.add method is jest.fn(). There is no mock implementation for it. If no implementation is given, the mock function will return undefined when invoked. That's why the math.add(1, 2) returns undefined.

You are testing the math module, then you should NOT mock it. But if you insist to do it. You can use math.add.mockReturnValue(3); before invoke the math.add(1,2). But it doesn't make sense, you can give any value you want. You didn't test the real math.add method. You just match your mock return value to the assertion expect(math.add).toHaveReturnedWith(3)

E.g.
math.js:

const add = (a, b) => a + b;
const subtract = (a, b) => b - a;
const multiply = (a, b) => a * b;
const divide = (a, b) => b / a;

module.exports = {
  add,
  subtract,
  multiply,
  divide,
};

math.test.js:

const math = require('./math');

jest.mock('./math.js');

test('calls math.add', () => {
  math.add.mockReturnValue(3);
  math.add(1, 2);

  expect(jest.isMockFunction(math.add)).toBeTruthy();

  expect(math.add).toHaveBeenCalled();
  expect(math.add).toHaveBeenCalledWith(1, 2);
  expect(math.add).toHaveReturned();
  expect(math.add).toHaveReturnedWith(3);
});

Test result:

 PASS  stackoverflow/71605818/math.test.js
  ✓ calls math.add (3 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |      20 |     100 |                   
 math.js  |     100 |      100 |      20 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.225 s
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文