I am trying to test my method that takes a hash and re-orders it. I currently have:
def sort_views
help = view_counter.sort_by { |route, length| length }.reverse.to_h
p help #just so I can see the output in the test
end
Then for my test I have:
describe "#sort_views" do
let(:result) do {
"/help_page/1" => 3,
"/about/2" => 1,
"/contact" => 1,
"/home" => 1,
"/index" => 2,
} end
it "then sorts them via the view count" do
expect(subject.sort_views).to be(result)
end
end
My issue is that the test passes.... However, I purposely have the order wrong at the moment in the result. Yet the p help in the method CORRECTLY re-orders it, so the output is actually different. I have tried eq and eql but I believe they just test structure? I know be and equal won't work...
For context my p help outputs: {"/help_page/1"=>3, "/index"=>2, "/about/2"=>1, "/home"=>1, "/contact"=>1}
when the test is run.
So is there a way for me to say test the order of the result hash in my test too without calling .sort_by { |route, length| length }.reverse.to_h on my result variable as well??
That's because the hashes are the same, see this post. Hashes don't really have a concept of order, when you call the sort_by
method it is converting the data to an array, ordering the array, and then returning an array. If you are converting the array to a hash you will lose the order essentially.
If you care about the order here, remove the to_h
and just deal with the data as an array instead. Then your tests should work.
You can use .to_a
in the test, and you don't need reverse in the sort.
view_counter.sort_by { |route, length| -length }
let(:result) do
{
"/help_page/1" => 3,
"/about/2" => 1,
"/contact" => 1,
"/home" => 1,
"/index" => 2,
}.to_a
end