Question

I'm trying to check multiple conditions over the same execution, in this case is just a post( :create , user: user.attributes ) but I would like to know in general what's the best approach.

Here is the complete example

describe UsersController do
describe 'CRUDL' do
    describe 'create' do
        let(:user) { User.new(username: "created") }
        let(:response) {  post( :create , user: user.attributes ) }


        it 'should respond with created(201) http message' do
            response.code.should == "201"
        end
        it 'should increment total users count' do
            expect{ response }.to change{User.count}.by(1)
        end
    end
end

The expect{ response }.to change{User.count}.by(1) part does not seem right. What would be the correct approach to test many assertion over the same code execution?

Was it helpful?

Solution

A word of caution, if you are using rspec-rails, there is already a response method add into the example object. Patching a custom let on top may result in difficult to debug errors.

With that being said, there isn't anything wrong with these tests. You should be only testing one thing per spec, which you are. The expect{}.to change{} part may seem weird because your let(:response) is both the action you want to test and the storage of the response object.

It may make more intuitive sense to have something like:

describe 'CRUDL' do
  context 'creating a user' do
    let(:normal_user) { User.new(username: "created") }

    def create_user(user)
      post( :create , user: user.attributes )
    end

    it 'responds with created(201) http message' do
      create_user normal_user

      expect(response.code).to eq '201'
    end

    it 'creates the user' do
      expect{ create_user normal_user }.to change{User.count}.by(1)
    end
  end
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top