John Fadria
John Fadria

Reputation: 1945

rspec data scope between test and model

I'm testing something like:

describe "#check_name" do
  it 'should raise ArgumentError with equal name' do
    @article = Factory.build(:article)
    @article.id = 3
    lambda { @article.check_name(@article.id) }.
      should raise_error(ArgumentError)
  end
end

And the model:

def check_name(article_id)
  tocheck = Article.find_by_id(article_id)
  if self.name == tocheck.name
    raise ArgumentError, "It has the same name!!!"
  end
end

Debugging the model, self has the values of the Factory build, it's ok. But tocheck is nil. Article.find_by_id(article_id) is nil.

If I'm calling @article.check_name() and the Article exists in the model, how is that is not possible to query?

Sorry, perhaps I don't understand the scope of the vars or the correct way to test this kind of code.

[UPDATE] It's about the scope of the ActiveRecord's find operation. What would be the correct way to test this raise?

Thanks in advance!!!

Upvotes: 1

Views: 279

Answers (1)

Peter Alfvin
Peter Alfvin

Reputation: 29389

ActiveRecord's find operations do database lookups and your Article object hasn't been saved to the database yet, hence the nil result.

While the Rails validation mechanisms may avoid the need to have a method like this and it's hard to specify what test approach would be best without seeing the whole model and it's constraints, I would think the choices are either:

  • Use a test double to return the find_by_id results, or
  • Create the record in the database instead of just "building it" and then build a new record with the same name, sending the check_name message to that new record

The latter might look like:

describe "#check_name" do
  it 'should raise ArgumentError with equal name' do
    article = Factory.create(:article)
    expect { Factory.build(:article).check_name(article.id) }.to raise_error(ArgumentError)
  end
end

assuming your article factory uses the same name for all articles. If it doesn't, you have to pass the the name of the first article as an argument to the build of the second article.

Upvotes: 2

Related Questions