Dpolehonski
Dpolehonski

Reputation: 958

Rspec, Rails, Do I need to get or post a request for every test

I'm very new to rspec, and rails, and ruby. I'm learning them at the moment. I find myself puting a get or post request in every individual test I perform which isn't very DRY. Do I need to keep issuing these requests for the test to work? or am i missing something fundamental?

EDIT:

For each test I'm performing I have to issue a get :page style request so that the controller will run the request. but when testing various aspects of the same action I repeatedly issue the same request and thus repeat the code. This is not DRY (Don't repeat yourself).

describe "Find Movies With Same Director" do
    it "should respond, and find the requested movie" do
      stubFind()
      id = "1"
      get :match_director, :id=>id
      response.code.should eq("200")
    end

    it "should search for movies with the same director" do
      id = "1"
      Movie.should_receive(:match_director).with(id)
      get :match_director, :id=>id
    end

    it "should pass all matching movies to view" do
      id = "1"
      Movie.should_receive(:match_director).with(id).and_return("")
      get :match_director, :id=>id
      assigns[:movies].should not_be nil
    end

    it "should pass a list of movies" do
      id = "1"
      Movie.stub(:match_director).and_return(stub_model(Movie))
      get :match_director, :id=>id

      assigns[:movies].should be_instance_of(Movie)
    end

  end

Upvotes: 3

Views: 553

Answers (1)

froderik
froderik

Reputation: 4808

If you are doing the same thing for several tests you can move them to a before block.

describe 'something' do
    it 'should do one thing' do
        common_thing
        specific_thing
    end

    it 'should do one thing' do
        common_thing
        specific_thing
    end
end

becomes

describe 'something' do
    before :each do
        common_thing
    end

    it 'should do one thing' do
        specific_thing
    end

    it 'should do one thing' do
        specific_thing
    end
end

If you want the common thing to be called only once for all tests then you replace before :each with before :all.

EDIT: after seeing you edit I think that you could put the call get :match_director, :id=>id in a method and use it instead:

def call_match_director
    get :match_director, :id=>id
end

Then it will be easy to add params to the call in one place. You can also put the id in a variable with the let construct:

let(:id) { "1" }

All in all like this:

describe "Find Movies With Same Director" do
  let(:id) { "1" }

  def call_match_director
    get :match_director, :id=>id
  end

  it "should respond, and find the requested movie" do
    stubFind()
    call_match_director
    response.code.should eq("200")
  end

  it "should search for movies with the same director" do
    Movie.should_receive(:match_director).with(id)
    call_match_director
  end

  it "should pass all matching movies to view" do
    Movie.should_receive(:match_director).with(id).and_return("")
    call_match_director
    assigns[:movies].should not_be nil
  end

  it "should pass a list of movies" do
    Movie.stub(:match_director).and_return(stub_model(Movie))
    call_match_director
    assigns[:movies].should be_instance_of(Movie)
  end
end

Upvotes: 3

Related Questions