At Woovi we use MongoDB as our primary database.
For our integration tests, we use an in memory database to ensure our queries and aggregates are working correctly.
It is madness to mock a database, it generates a lot of false positives, and it won't give confidence to upgrade.
How to assert ObjectId
?
ObjectIds are small, likely unique, fast to generate, and ordered.
ObjectId
is the primary key of each MongoDB document.
A common test scenario is to validate if a given ObjectId
is equal to another ObjectId
In a naive approach, you use assert like this
expect(objectIdA).toBe(objectIdA);
This does not work because ObjectId
are an Object in JavaScript, and even if they have the same value, they will be in different places in the memory.
The way to solve this, it is to convert the ObjectId
to string using toString() method, and then make the assertion
expect(objectIdA.toString()).toBe(objectIdA.toString());
What if you want to assert 2 complex objects, like this one:
const obj = {
_id: new ObjectId('5c9b1b9b9b9b9b9b9b9b9b9b'),
name: 'test',
myarr: [
new ObjectId('5c9b1b9b9b9b9b9b9b9b9b9b'),
new ObjectId('5c9b1b9b9b9b9b9b9b9b9b9b'),
new ObjectId('5c9b1b9b9b9b9b9b9b9b9b9b'),
],
my: {
nested: {
field: new ObjectId('5c9b1b9b9b9b9b9b9b9b9b9b'),
},
},
};
Recursion for the rescue
We want to convert all ObjectId values to string, the most elegant way of doing this is using recursion:
export const mongooseObjectIdToString = (data: any) => {
// no value, return value
if (!data) {
return data;
}
// traverse the array
if (Array.isArray(data)) {
return data.map(d => mongooseObjectIdToString(d));
}
// transform ObjectId to string
if (
ObjectId.isValid(data) &&
data.toString().indexOf(data) !== -1
) {
return data.toString();
}
// traverse nested object
if (typeof data === 'object' && !Array.isArray(data)) {
return Object.keys(data).reduce((prev, curr) => ({
...prev,
[curr]: mongooseObjectIdToString(data[curr]),
}), {});
}
return data;
};
mongooseObjectIdToString
will call itself when it finds an array or a nested object, otherwise will just convert the ObjectId
to String, or just return any other data type.
The assert would then be:
expect(mongooseObjectIdToString(obj)).toEqual(mongooseObjectIdToString(anotherObj));
In Short
Recursion is not only useful to solve Fibonacci, but can also be applied to solve real problems, like traversing a complex object applying some transforming.
This approach can be generalized to apply any transforming in any complex object, comment with your generalized algorithm, and where you are going to use it.
Woovi
Woovi is a Startup that enables shoppers to pay as they like. To make this possible, Woovi provides instant payment solutions for merchants to accept orders.
If you want to work with us, we are hiring!
Top comments (0)