angular - Jest enhetstest sjekker etter unik verdi


Jeg er ny på enhetstester og på å skrive dem for komponentene og klassene mine. Jeg har en metode som filtrerer ut duplikatnumre med samme ID. Jeg skrev denne metoden:

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;
}

Mine tester er slik:

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));
            }
        }
    });
});

Testen vil lage noen mock-data for testens formål, slik det sees i begynnelsen. Jeg er ikke helt sikker på hvordan jeg tester om orderNumber er unik for sin receipt.id.

Finnes det en måte å bruke noen native jest-metoder på?

Eksempel :

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

Det er det groupByOrderNumber() i bunn og grunn gjør.

Svar #1

Du kan bare lage en nestet ordbok og umiddelbart feile hvis du ser en duplisert identifikator på den nestede ordboken når du sjekker ordrenummeret.

På denne måten unngår vi å gå gjennom hele samlingen mer enn én gang.

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] = ""
    }
  }
}

bare for gøy skrev jeg en liten stub for å kjøre testReceipts-testen

// 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!");
    }
  })
}


Svar #2

Først må du lage et kart som lagrer kvitteringene etter id, slik at du kan få tilgang til alle kvitteringene med samme id veldig enkelt.

Deretter, for hver kvitterings-ID, hent ordrenummeret.

Og til slutt, sjekk at de ordrenumrene er unike (konverter arrayet til et Set og sammenlign lengden deres).

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}`);
  }
}

Relaterte artikler