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