1
votes

I am a testing noob going through Everyday Rails Testing with RSpec book.

There are basically two request spec files - One for API:

# spec/requests/projects_api_spec.rb

describe 'Projects API', type: :request do
  it 'creates a project' do
    user = FactoryBot.create(:user)
    project_attributes = FactoryBot.attributes_for(:project)

    expect {
        post api_projects_path, params: {
          user_email: user.email,
          user_token: user.authentication_token,
          project: project_attributes
        }
    }.to change(user.projects, :count).by(1)

    expect(response).to have_http_status(:success)
  end
end

And the other one replacement of controller spec:

# spec/requests/projects_spec.rb

RSpec.describe "Projects", type: :request do
  context "as an authenticated user" do
    before do
      @user = FactoryBot.create(:user)
    end

    context "with valid attributes" do
      it "adds a project" do
        project_params = FactoryBot.attributes_for(:project)
        sign_in @user
        expect {
          post projects_path, params: { project: project_params }
        }.to change(@user.projects, :count).by(1)
      end
    end
  end
end

Can't we just have one integration test or request spec?

1

1 Answers

2
votes

These test different endpoints (api_projects_path and projects_path) and have different authorisation methods.

Even if tests (here "tests" is for individual tests aka it blocks) are or look mostly identical - in the long run they may diverge. And for API it's important to preserve behaviour. As for file organisation - sure these may be put into single file and share some common setup (to follow DRY principle).

But on the other hand - for better api separation and stability some copy-paste-programming is acceptable - this way you're less likely to inadvertently change api tests when implementing some changes to non-api-path in the future.