【问题标题】:Jest Unit Test check for unique value开玩笑单元测试检查唯一值
【发布时间】:2021-05-09 20:26:36
【问题描述】:

我是单元测试的新手,并为我的组件和类编写它们。 我有一种过滤重复数字但具有相同 ID 的方法。 我写了这个方法:

public groupByOrderNumber(
    deliveryReceipts: DeliveryReceiptSearch[]
): Map<string, Map<string, DeliveryReceiptItemSearchResult[]>> {
    const groupedDeliveryReceipts = new Map<string, Map<string, DeliveryReceiptItemSearchResult[]>>();

    for (const receipt of deliveryReceipts) {
        const receiptId: string = receipt.id;
        groupedDeliveryReceipts.set(receiptId, new Map<string, DeliveryReceiptItemSearchResult[]>());
        for (const item of receipt.items) {
            const orderNumber = item.orderNumber;
            if (groupedDeliveryReceipts.get(receiptId).has(orderNumber)) {
                groupedDeliveryReceipts.get(receiptId).get(orderNumber).push(item);
            } else {
                groupedDeliveryReceipts.get(receiptId).set(orderNumber, [item]);
            }
        }
    }

    return groupedDeliveryReceipts;
}

我的测试是这样的:

describe('groupByOrderNumber', () => {
    const deliveryReceipts: DeliveryReceiptSearchMock[] = DeliveryReceiptSearchMock.createListOfReceipts();

    it('should not contain identical orderNumbers', () => {
        const dReceipts: Map<string, Map<string, DeliveryReceiptItemSearchResult[]>> = service.groupByOrderNumber(
            deliveryReceipts
        );

        for (const receipts of deliveryReceipts) {
            const receiptId: string = receipts.id;
            for (const item of receipts.items) {
                const orderNumber = item.orderNumber;
                expect(dReceipts.get(receiptId).has(orderNumber)).toIn
          expect(dReceipts.get(receipts.id).set(orderNumber, [item])).not.toEqual(dReceipts.get(receipts.id).get(orderNumber));
            }
        }
    });
});

测试将模拟一些数据以用于测试,如开头所示。 我不太确定如何测试 orderNumber 是否是其 receipt.id 独有的。

有没有办法使用一些原生的 jest 方法?

例子:

receipt.id ('9876') -> orderNumber ('123')
receipt.id ('101112') -> orderNumber ('123')

groupByOrderNumber() 基本上就是这样做的。

【问题讨论】:

  • 仍在学习 Jest,但您可以尝试从空数组开始,然后检查数组中是否存在订单号。类似于:expect(testArray).not.toContain(orderNumber)。如果没有失败,则将该订单号添加到数组中。
  • 是的,我明白你的想法。我希望orderNumber 存在于数组中,但我希望它对于相应的receipt.id 是唯一的。就像我有两张收据,orderNumber 相同,receipt.id 不同。
  • 你能在 stackblitz 或类似的东西中重新创建它吗?它使帮助变得更容易,并且可能更详细地说明您当前的测试用例做了什么以及结果与您的预期有何不同

标签: angular typescript unit-testing jestjs


【解决方案1】:

首先,您需要创建一个按 id 存储收据的地图,这样您就可以非常轻松地访问具有相同 id 的所有收据。

然后,对于每个收据 id,获取订单号。

最后,检查这些订单号是否唯一(将数组转换为 Set 并比较它们的长度)。

const deliveryReceipts = [{
  id: '1',
  orderNumber: '123'
}, {
  id: '1',
  orderNumber: '234'
}, {
  id: '2',
  orderNumber: '123'
}, {
  id: '3',
  orderNumber: '456'
}, {
  id: '3',
  orderNumber: '456'
}];
const receiptsMap: {
  [id: string]: DeliveryReceiptSearchMock[]
} = {};

// This iterates over every receipt and stores them in a map based on their ID.
for (const receipt of deliveryReceipts) {
  const receiptId: string = receipt.id;
  receiptsMap[receiptId] = [...receiptsMap[receiptId] || [], receipt];
}

// For each receiptId, let's test if the orderNumbers are unique.
for (const receiptId of Object.keys(receiptsMap)) {
  const allOrderNumbers = receiptsMap[receiptId].map((receipt) => receipt.orderNumber);
  const uniqueOrderNumbers = [...new Set(allOrderNumbers)];
  // expect(allOrderNumbers.length).toBe(uniqueOrderNumbers.length)
  expectToEqual(receiptId, allOrderNumbers.length, uniqueOrderNumbers.length);
}

function expectToEqual < T > (receiptId: string, given: T, expected: T): void {
  if (given === expected) {
    console.log(`id ${receiptId} ✓`);
  } else {
    console.log(`id ${receiptId} ✗ Expected ${expected} but found ${given}`);
  }
}

【讨论】:

    【解决方案2】:

    如果您在检查订单号的嵌套字典上看到重复的标识符,您可以创建一个嵌套字典并立即失败。

    通过这种方式,我们避免在整个集合中循环多次。

    function testReceipts(deliveryReceipts) {
      const orderCheck = {}
      for (const receipt of deliveryReceipts) {
        orderCheck[receipt.id] = Boolean(orderCheck[receipt.id]) ? orderCheck[receipt.id] : {};
        for (const item of receipt.items) {
          const orderNumber = item.orderNumber;
          expect(!orderCheck[receipt.id].hasOwnProperty(orderNumber)).toBeTruthy();
          orderCheck[receipt.id][orderNumber] = ""
        }
      }
    }
    

    我写了一个小存根来运行 testReceipts 测试

    // arrange
    const knownGood = [{
        id: 1,
        items: [{
          orderNumber: 1
        }, {
          orderNumber: 2
        }, {
          orderNumber: 3
        }]
      },
      {
        id: 2,
        items: [{
          orderNumber: 1
        }, {
          orderNumber: 2
        }, {
          orderNumber: 3
        }]
      }
    ];
    
    const knownBad = [{
        id: 1,
        items: [{
          orderNumber: 1
        }, {
          orderNumber: 2
        }, {
          orderNumber: 1
        }]
      },
      {
        id: 2,
        items: [{
          orderNumber: 1
        }, {
          orderNumber: 2
        }, {
          orderNumber: 3
        }]
      }
    ];
    
    // assert
    testReceipts(knownGood); // pass.
    testReceipts(knownBad); // Bad code, bad!
    
    // I didn't want to install Jest, so I made my own little expect wrapper. You'd obviously use Jest.
    function expect(arg) {
      return ({
        toBeTruthy: () => {
          if (!Boolean(arg)) console.error("Bad code, bad!");
        }
      })
    }
    
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-01
      • 2018-09-10
      • 2022-08-07
      • 1970-01-01
      • 2021-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多