angular - Jest enhetstest kontrollera unikt värde
Jag är ny på enhetstester och på att skriva dem för mina komponenter och klasser. Jag har en metod som filtrerar bort duplicerade nummer men med samma ID. Jag skrev denna metod:
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;
}
Mina tester ser ut så här:
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));
}
}
});
});
Testet kommer att simulera viss data för testets syfte som ses i början. Jag är inte riktigt säker på hur jag testar om orderNumber är unikt för dess receipt.id.
Finns det ett sätt att använda några inbyggda jest-metoder?
Exempel :
receipt.id ('9876') -> orderNumber ('123')
receipt.id ('101112') -> orderNumber ('123')
Det är i princip vad groupByOrderNumber() gör.
Svar #1
Du kan helt enkelt skapa ett nästlat ordbok och omedelbart misslyckas om du ser en duplicerad identifierare när du kontrollerar ordernumret i det nästlade ordboken.
På detta sätt undviker vi att loopa mer än en gång över hela samlingen.
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] = ""
}
}
}
bara på skoj skrev jag ett litet stub för att köra testReceipts-testet
// 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 behöver du skapa en karta som lagrar kvittona efter dess id, så att du kan komma åt alla kvitton med samma id mycket enkelt.
Sedan, för varje kvittos-id, hämta ordernumret.
Och till sist, kontrollera att de där ordernumren är unika (konvertera arrayen till ett Set och jämför deras längd).
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}`);
}
}