DEV Community

Vasily Polovnyov
Vasily Polovnyov

Posted on

4 2

RSpec: do not verify hash keys separately

Sometimes I come across three separate checks in specs to make sure the hash is OK: there are keys, there are values, values have the right type.

RSpec.describe UserSerializer do
  describe "#as_json" do
    let(:user) do
      build(:user,
        first_name: "Bart",
        last_name: "Simpson",
        tel: "+777123")
    end
    let(:json) { described_class.new(user).as_json }

    it "has keys" do
      expect(json).to include(:first_name, :last_name, :tel)
    end

    it "has types" do
      expect(json[:first_name]).to be_kind_of(String)
      expect(json[:last_name]).to be_kind_of(String)
      expect(json[:tel]).to be_kind_of(String)
    end

    it "has values" do
      expect(json[:first_name]).to eq(user.first_name)
      expect(json[:last_name]).to eq(user.last_name)
      expect(json[:tel]).to eq(user.tel)
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

This spec is more confusing than helpful: when you change fields, you have to update three tests; it's hard to immediately understand what the serializer returns.

Better to use include matcher and skip type checks (it's not the responsibility of the test):

RSpec.describe UserSerializer do
  describe "#as_json" do
    it "includes first name, last name and tel" do
      user = build(:user,
        first_name: "Bart",
        last_name: "Simpson",
        tel: "+777123")
      json = described_class.new(user).as_json

      expect(json).to include(
        first_name: "Bart",
        last_name: "Simpson",
        tel: "+777123"
      )
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

AWS GenAI LIVE image

How is generative AI increasing efficiency?

Join AWS GenAI LIVE! to find out how gen AI is reshaping productivity, streamlining processes, and driving innovation.

Learn more

Top comments (4)

Collapse
 
robcodes profile image
RobCodes • Edited

What do you think about taking it one step further?

expect(json).to contain_exactly({
first_name: "Bart",
last_name: "Simpson",
tel: "+777123"}
)

Collapse
 
vasily profile image
Vasily Polovnyov

Looks awesome. Thanks!

Collapse
 
colocodes profile image
Damian Demasi

Thanks, Vasily! This helped me to keep my code cleaner. ⭐️

AWS Q Developer image

Your AI Code Assistant

Ask anything about your entire project, code and get answers and even architecture diagrams. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Start free in your IDE