mehulkar
mehulkar

Reputation: 4964

Test that method has a default value for an argument with RSpec

How can I test that a method that takes an argument uses a default value if an argument is not provided?

Example

# this method shouldn't error out
# if `Post.page_results` without a parameter
class Post
  def self.page_results(page=1)
    page_size = 10
    start = (page - 1) * page_size
    finish = start + page_size
    return Page.all[start..finish]
  end
end

How do I check in rspec that page equals 1 if page_results is called without argument?

Upvotes: 4

Views: 2389

Answers (3)

Thomas Koppensteiner
Thomas Koppensteiner

Reputation: 717

Testing that the page param has the default value set, is most likely not what you should test. In most cases, it is better to test the behaviour instead of the implementation (Talk from Sandy Metz about testing). In your case, you should test if the expected set of Pages is returned, when page_results is called without params (default case).

Here is an example of how you could do this:

describe Post do
  describe ".page_results" do
    context "when Pages exist" do
      subject(:pages) { described_class.page_results(page) }

      let(:expected_pages_default) { expected_pages_page_1 }
      let(:expected_pages_page_1)  { Page.all[0..10] }
      let(:expected_pages_page_2)  { Page.all[10..20] }

      before do
        # Create Pages
      end

      context "when no page param is give " do
        # HINT: You need to redefine subject in this case. Setting page to nil would be wrong
        subject(:pages) { described_class.page_results }

        it { expect(pages).to eq expected_pages_default }
      end

      context "when the page param is 1" do
        let(:page) { 1 }

        it { expect(pages).to eq expected_pages_page_1 }
      end

      context "when the page param is 2" do
        let(:page) { 2 }

        it { expect(pages).to eq expected_pages_page_2 }
      end
    end

    context "when no Pages exist" do
      # ...
    end
  end
end

Upvotes: 3

John Small
John Small

Reputation: 973

I use before_validation to set defaults e.g

before_validation do
      self.some_attribute ||=a_default_value
end

That leaves open the possibility to override the default

SomeClassWithDefaultAttributes.create(some_attribute:a_non_default_value)

Keep in mind that if #before_validation returns false, then the validation will fail

Upvotes: -1

Arjan
Arjan

Reputation: 6274

describe Post do
  describe '#page_results' do
    let(:post) { create :post }

    context 'without arguments' do
      it { post.page_results.should eq 1 }
    end
  end
end

The create :post statement is how you would do it with FactoryGirl. But you could of course mock or stub out your model.

Update

describe Post do
  describe '#page_results' do

    context 'without arguments' do
      it { Post.page_results.should eq 1 }
    end

    context 'with arguments' do
      it { Post.page_results('foo').should eq 'bar' }
    end
  end
end

Upvotes: -1

Related Questions