General concept is you have to have a known state & fixed data (your data can't be dynamic every time you run it, otherwise, it can be hard to test for, unless the dynamic data is a date/time stamp that you can compare against - numerically compare timestamp value for greater/less than between starting row vs other rows, etc. and move along)
Once you have fixed data, you want to start from a known state (what sorting is the default? ascending/descending, etc.) If you know that the default sort will always be same, then good, otherwise to be safe, you can also force sorting to a given state to start from (unless you need to test default sort state). Then perform your sort and verify sort order.
You can verify sort order when you have fixed data as you know specifically what order it should always appear in. e.g. some row/cell will always be at row x when sorted A-Z and row y when sorted Z-A.
Exact method to verify sort depends on your grid/table implementation. Simply click whatever elements that cause a sort to occur, then simply follow up with a getText(), getAttribute(), etc. on some expected row A column B, asserting that it should contain the expected sorted value. Can do this for simply one row/cell or multiple. Failure of assertion means it wasn't sorted the way you expected.
You would assert the actual value that is extracted with getText(), getAttribute(), etc. against the expected value that is hard coded but configurable in your test data (e.g. in your test code as a variable/constant/page object locator, or in Java property file, CSV file, etc.)