如何保持控制器规格及其模拟DRY?

时间:2014-02-03 22:01:15

标签: ruby-on-rails rspec

我被告知这是编写它阻止的控制器的正确方法:

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" => user.email, "name" => user.name, "password" => user.password, "password_confirmation" => 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

但我很惊讶,因为它对我来说似乎并不干净。假设我想在这里创建两个“上下文”。 user.update_attributes调用返回false并返回true的一个。我的意思是简单地复制粘贴两个块并调整一个小参数吗?

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" => user.email, "name" => user.name, "password" => user.password, "password_confirmation" => 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" => user.email, "name" => user.name, "password" => user.password, "password_confirmation" => 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

我希望rspec允许我编写这种结构:

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

注意它为相同的上下文阻止的倍数,因为它不是一个期望阻止一个好的做法,因为它允许你看到究竟什么不起作用?你是怎么想用模拟做的?

0 个答案:

没有答案