代码之家  ›  专栏  ›  技术社区  ›  Aleksandar Dimitrov

Jest中模拟调用论证的模糊浮点检查

  •  0
  • Aleksandar Dimitrov  · 技术社区  · 4 年前

    给定一个带有签名的函数

    interface Position {
      x: number, y: number
    }
    
    function f(position: Position): void { … }
    

    我想在测试中模仿它

    // given
    const f = jest.fn()
    
    // when
    // exercise SUT
    
    // then
    expect(f).toHaveBeenCalledWith<Position>({x: 1.0, y: 1.0});
    

    但不幸的是,我正在处理浮点问题,所以我需要检查以留出一些余地。现在,我 能够 做

    expect(f.mock.calls[0][0].x).toBeCloseTo(1, 1);
    expect(f.mock.calls[0][0].y).toBeCloseTo(1, 1);
    

    但那会变老 真实的 快速的有一张票,Jest维护者 don't seem to think warrants inclusion in Jest 和一个包到 match using expect 但它并没有做我想做的事!类似于:

    expect(f).toHaveBeenCalledWith(
      expect.objectContaining({
        x: expect.numberCloseTo(1), 
        y: expect.numberCloseTo(1)
       });
    

    有这样的事情吗?还是我必须自己滚?

    0 回复  |  直到 4 年前
        1
  •  0
  •   Aleksandar Dimitrov    4 年前

    正如Aleksey已经暗示的那样,我需要编写自己的自定义匹配器。所以,它开始了:

    declare global {
      namespace jest {
        interface Expect {
          numberCloseTo(expected: number, precision?: number): any;
        }
      }
    }
    
    expect.extend({
      numberCloseTo(actual: number, expected: number, precision: number = 2) {
        expect(actual).toBeCloseTo(expected, precision);
        return { message: () => "This shouldn't happen.", pass: true };
      },
    });
    

    以下是我如何使用它:

    expect(f).toHaveBeenCalledWith(
      expect.objectContaining<Position>({
        x: expect.numberCloseTo(1, 1),
        y: expect.numberCloseTo(1, 1),
      })
    );
    

    扩展现有的匹配器在Jest中非常尴尬,我想 that's by design 。所以我们需要包含一个伪消息。

    仅TS declare global 如果您使用Flow或纯JS,则可以删除等。