代码之家  ›  专栏  ›  技术社区  ›  Dan Dascalescu

包括开玩笑的toBeCloseTo。toMatchObject

  •  1
  • Dan Dascalescu  · 技术社区  · 7 年前

    我正在测试一个对象是否匹配一组字段,但其中一个是浮点,我需要使用 .toBeCloseTo .这怎么可能在一天之内完成 expect ?

    expect(foo).toMatchObject({
      bar: 'baz',
      value: ???.toBeCloseTo(5),  // TODO
    });
    

    我可以用 expect(foo.value).toBeCloseTo(5) ,但我不想把逻辑分成多个部分 expect s、 每个浮点数对应一个。

    1 回复  |  直到 7 年前
        1
  •  17
  •   Brian Adams    7 年前

    问题

    这个 docs for toMatchObject 声明“您可以根据值或匹配器匹配属性”。

    不幸地 toBeCloseTo 目前无法作为非对称匹配器使用,看起来 these are the only asymmetric matchers currently provided by Jest .


    解决方案

    如果您使用的是Jest v23或更高版本,您可以创建自己的,本质上是复制的 toBeCloseTo 使用 expect.extend :

    expect.extend({
      toBeAround(actual, expected, precision = 2) {
        const pass = Math.abs(expected - actual) < Math.pow(10, -precision) / 2;
        if (pass) {
          return {
            message: () => `expected ${actual} not to be around ${expected}`,
            pass: true
          };
        } else {
          return {
            message: () => `expected ${actual} to be around ${expected}`,
            pass: false
          }
        }
      }
    });
    
    const foo = {
      bar: 'baz',
      value: 4.9999
    };
    
    test('foo', () => {
      expect(foo.value).toBeAround(5, 3);  // SUCCESS in Jest > v20
      expect(foo).toMatchObject({
        bar: 'baz',
        value: expect.toBeAround(5, 3)  // SUCCESS only in Jest > v23
      });
    });
    

    注意 预料延伸 创建一个匹配器,可以在函数中使用,如 toMatchObject 只是开玩笑v23及更高版本。


    替代方案

    从…起 this post 一位开玩笑的合作者说:“虽然这是暗示,但 目前没有记录 ,Jest断言将不对称匹配器对象评估为 defined in Jasmine ".

    使用 the logic from toBeCloseTo 可以这样创建:

    const closeTo = (expected, precision = 2) => ({
      asymmetricMatch: (actual) => Math.abs(expected - actual) < Math.pow(10, -precision) / 2
    });
    
    const foo = {
      bar: 'baz',
      value: 4.9999
    };
    
    test('foo', () => {
      expect(foo).toMatchObject({
        bar: 'baz',
        value: closeTo(5, 3)  // SUCCESS
      });
    });