I am trying to do a complete match using objectContaining instance in jest.
Below is the example object I am trying to match:
const queryCommandInput = {
KeyConditionExpression: '---keyConditionExpression---',
ProjectionExpression: '---projectionExpression----',
FilterExpression: '---filterExpression----',
ExpressionAttributeValues: { //[1] - Unable to match from here
'value1': { S: 'example1' },
'value2': { S: 'example2' },
'value3': { N: 12345 },
},
TableName: 'tableName'
}
const queryCommand = new QueryCommand(queryCommandInput);
//[2]
expect(DynamoDBClient.prototype.send).toBeCalledWith(expect.objectContaining({input: expect.objectContaining(queryCommandInput) }))
[1] - Unable to do a multilevel match without using multi objectContaining ([2])
I could have another object containing, and then another objectContaining after that. But not able to find any other better way to automatically iterate and match all the key/values
Found the solution. I am sure this will be helpful for a lot of developers out there.
Destructuring and overriding the behaviour for the properties which we know a match would fail, works!!
In this scenario, queryCommand is an instance of a class QueryCommand. The below statement would fail because even though the inputs are the same, the instances are different.
expect(DynamoDBClient.prototype.send).toBeCalledWith(queryCommand) //the queryCommand is a different instance from the instance being sent to the send method of DynamoDBClient conrtuctor, hence it fails.
That is why I was using the objectContaining class, but that only matches one level. If the object is nested, multiple nested objectContaining must be constructed. The best way is to not use an objectContaining constructor, but to match the instances itself and restructure it so that we only check the types of the properties which we know will change, and complete/deep check the properties that we want.
expect(DynamoDBClient.prototype.send).toBeCalledWith({ ...queryCommand, middlewareStack: expect.any(Object) })