Test fails as expected sort order using orderBy in lodash gives shuffled records

Hi,
I have a usecase where I need to validate whether the response has all records sorted by a column and in the respective sorting order. I have used ‘lodash’ for this. I have used ‘orderBy’ function of lodash to get the expected sorting and compared it against the actual response by using ‘eql’. The following is sample code that I have written

image

The above code works. My response has an array of records. The expected sort order has records as in response but in shuffled order. More than half of the records are shuffled in the Expected sort order. Due to this when I compare the expected v/s actual response, my test fails though the sorting order is Ascending in both cases. My response has a key ‘branchName’ using which the reponse is sorted and the value of ‘branchName’ for most of the elements of the records array starts with “TEST” and hence the shuffling is happening I guess. The following is my response body
image
image

Is there a way to get the expected sort order without shuffling or how do I resolve this? Can anyone please suggest?

Please add a example response that we could try out with

Hi,
Thanks for replying. I have tried console.log of the expected sort order and the actual response. I have added the screenshots below.


In the above two screenshots, the same record is in different array element positions for expected sort order and actual response though the ordering is ascending. Due to this when I compare, the test fails. I hope this helps. Any details to be shared,please let me know. Kindly suggest be a solution.Thank you

If you don’t mind Please add a example json as text , so that we can try the same thing . Screenshots Is hard to understand and debugging

Hi,
Please find the POST request body below
{
“pageNumber”: 1,
“pageSize”: 10,
“sortParams”: [
{
“sortColumn”: “BranchName”,
“sortOrder”: “Asc”
}
],
“filterParams”: {
“filterColumn”: “BranchName”,
“FilterValue”: “TEST”,
“operator”: “contains”,
“logicOperator”: “and”,
“isCaseSensitive”: false,
“filterList”: null
}
}

The following is the response body
{

"pageNumber": 1,

"pageSize": 10,

"totalPages": 74,

"totalRecordsCount": 735,

"succeeded": true,

"message": null,

"errors": null,

"data": [{
        "branchId": 4,
        "branchCode": "AAR",
        "branchName": "TEST Aar",
        "branchCodeWithName": "AAR - TEST Aarhus",
        "companyId": 39,
        "companyCode": "LDK",
        "companyCompanyName": null,
        "companyCompanyCodeWithName": null
    },
    {
        "branchId": 7,
        "branchCode": "ABZ",
        "branchName": "TEST Aberdeen",
        "branchCodeWithName": "ABZ - TEST Aberdeen",
        "companyId": 90,
        "companyCode": "LUK",
        "companyCompanyName": null,
        "companyCompanyCodeWithName": null
    }

]
}

This is the sample code I have written
pm.test(“Validate that the response values are sorted by BranchName in ‘asc’”,() => {

var sortExpected = _.orderBy(bodyData.data,[‘branchName’],[‘asc’]);

console.log(sortExpected)

console.log(bodyData.data) //response

pm.expect(bodyData.data).to.eql(sortExpected)

});

I hope this helps…KIndly help

no i deleted a comment thats why it was showing that .

I believe that the names are not in the same “case” , and it seems like lodash sort has a>Z . so thats why it looks like the result is messed up . Use something like:

 let _ = require("lodash")
 var sortExpected = _.orderBy(bodyData.data, [data => data.branchName.toLowerCase()], ["desc"]);

here orderby converts all the names to lowercase before taking it for sort comparison , this allows us to get proper order with out the mess up of upper and lowercase strings

1 Like

Hi,
Thanks for the reply. This is working fine. Thanks for resolving.
This means instead of alphabetical order, lodash is using ASCII values to sort?
Also I have a query here, for few other use cases where names are present I tried with and without using toLowerCase() in orderBy() and its working fine. So Is it required to use toLowerCase() in orderBy(). Also what is the right way to sort strings in postman with a sorting column and order? Is lodash the best way? Thank you again.

1 Like

yes you can also use

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

array,sort ,

the ascii comparison is javascript behavior , in javascript a>Z because asci value of Z is 90 and a is 97

https://www.w3schools.com/charsets/ref_html_ascii.asp

  console.log("a".charCodeAt(0))

array.sort

  sortedarray= bodyData.data.sort((a,b)=>b.branchName.localeCompare(a.branchName))
1 Like

Thanks alot for sharing this. I actually have almost 10 to 11 APIs with the same usecase where just the sortColumn and filterValue changes.Rest is same. In my usecase I have only the response. To use localeCompare() I need a string and compareString. One string would be the branchName from the reponse array. How about the other string?
Otherwise may be I can use response array and lodash expectedSortOrder and compare both? I tried but getting issues…How can this be done? Is it getting too complicated? What can be done?

You can write any compare function as you want and pass to array.sort , that was one of the example.

If you just want to sort multiple columns , using lodash as you used is the best way.

No need to re invent the wheel

Fine…Thank you so much for responding very quickly and sharing so much of useful information …It was really helpful…

3 Likes

No issues :heart_eyes: welcome to the community

3 Likes

Thank you

I just have one more query…I hope u don’t mind.Can I write the below statement
var sortExpected = _.orderBy(bodyData.data, [data => data.branchName.toLowerCase()], [“desc”]);

within a function at may be a collection or a folder level and reuse it in other requests with same usecase by just passing the sorting column Name and sorting order?
Or writing the same statement for every request is a better way here?

You can do that , just mention comment saying there is collection script else you will forget there was some script in collection or folder level

Ok… I have tried doing this at collection level and calling the function in the request…But it says function isn’t defined…If u don’t mind can u share an example to do this…Thanks in advance

You cannot call function from different scopes. pass field name as variable , update it from pre request and sort in collection test script and store it as sortedareay as variants

Ok…Still trying…One query which I have since long is …For example if actual response array and sortExpected array doesn’t match, my test fails and it shows Assertion Error:array[10] to deeply equal array[10] …Should I consider that this error occurred because the test failed or there is something wrongly written in the test script? Please reply

It means test failed , the array was not equal

So test failed, just console.log both the expected and actual arrays and see the difference yourself to understand

Yes I have done that…I require ‘asc’. Just tested with ‘desc’,then got that error. So just had a doubt. Thank you

Also
Is the following a valid test…It is working but can I apply && between pm.expect

pm.test(“Validate that the response has records retrieved by both filter values”, function () {

for(i=0;i<bodyData.data.length;i++)

{
res=bodyData.data[i].branchCode;

res1=bodyData.data[i].branchName;

pm.expect(res).to.eql(value1) && pm.expect(res1).to.include(value2)

} });

Can I write this way