title: How do I keep a controller spec and its mocks DRY?
body: <p>I'm told this is the correct way to write a controller it block:</p>
  
  <pre><code>describe UsersController do
    let(:user){ mock_model(User, id: 2, name: "Jimbo", email: 'jimbo@email.com', password: 'passwordhuzzah', password_confirmation: 'passwordhuzzah') }
  
    describe 'PATCH #update' do
      it "should fail in this case" do
        User.should_receive(:find).with(user.id.to_s).and_return user      
        user.should_receive(:update_attributes).with({ "email" =&gt; user.email, "name" =&gt; user.name, "password" =&gt; user.password, "password_confirmation" =&gt; user.password_confirmation }).and_return true
  
        patch :update, id: user.id, user: { email: user.email, name: user.name, password: user.password, password_confirmation: user.password_confirmation }
  
        flash[:error].should == "could not update user"
        response.status.should == 200
      end
    end
  end
  </code></pre>
  
  <p>But I am surprised, because it doesn't seem DRY to me. Let's say I want to create two 'contexts' here. One where the <code>user.update_attributes</code> call returns false and returns true. Am I meant to simply copy paste two it blocks and tweak that one tiny argument?</p>
  
  <pre><code>describe UsersController do
    let(:user){ mock_model(User, id: 2, name: "Jimbo", email: 'jimbo@email.com', password: 'passwordhuzzah', password_confirmation: 'passwordhuzzah') }
  
      it "should pass in this case" do
        User.should_receive(:find).with(user.id.to_s).and_return user      
        user.should_receive(:update_attributes).with({ "email" =&gt; user.email, "name" =&gt; user.name, "password" =&gt; user.password, "password_confirmation" =&gt; user.password_confirmation }).and_return true
  
        patch :update, id: user.id, user: { email: user.email, name: user.name, password: user.password, password_confirmation: user.password_confirmation }
  
        flash[:error].should == "updated user"
        response.status.should == 302
      end
  
      it "should fail in this case" do
        User.should_receive(:find).with(user.id.to_s).and_return user      
        user.should_receive(:update_attributes).with({ "email" =&gt; user.email, "name" =&gt; user.name, "password" =&gt; user.password, "password_confirmation" =&gt; user.password_confirmation }).and_return false
  
        patch :update, id: user.id, user: { email: user.email, name: user.name, password: user.password, password_confirmation: user.password_confirmation }
  
        flash[:error].should == "could not update user"
        response.status.should == 200
      end
    end
  end
  </code></pre>
  
  <p>I was hoping rspec would allow me to write this sort of structure:</p>
  
  <pre><code>describe 'PATCH #update' do
     before {} 
     context 'when attributes can be updated' do
           before {}
           it "should set the flash" do end
           it "should set the status" do end
      end
      context 'when attributes can\'t be updated' do
           before {}
           it "should set the status" do end
           it "should set the flash" do end
      end
   end
  </code></pre>
  
  <p><strong>Note the multiple it blocks for the same contexts, because isn't one expectation per it block a good practise because it allows you to see exactly what's not working? How are you meant to do this with mocks?</strong></p>