简单的rspec问题

时间:2011-06-22 20:02:54

标签: ruby-on-rails testing controller rspec

我真的很想学习rspec :(所以我希望你能在控制器中给我一些非常简单的创建动作的帮助。我想用Rspec :: mocks来做这个,因为我认为这是方法吗?而不是在测试时必须打到数据库。

我有一个before_filter:

def find_project
   @project= Project.find_by_id(params[:project_id])
end

创建操作如下所示:

def create
  @batch = Batch.new(params[:batch])
  @batch.project = @project

  if params[:tasks]
    params[:tasks][:task_ids].each do |task_id|
      @batch.tasks << Task.find(task_id)
    end
  end

  if @batch.save
    flash[:notice] = "Batch created successfully"
    redirect_to project_batch_url(@project, @batch)
  else
    render :new
  end
end

@batch.project = @project如何定义@project,我真的很怀疑?还有整个params[:tasks][:task_ids].each部分..雅...整个事情:(

对不起这个新手问题 - 希望你们能帮助或至少指出我正确的方向:)

由于

2 个答案:

答案 0 :(得分:0)

控制器规范的想法是检查操作是否正在设置实例变量,以及根据需要重定向/呈现。要设置规范,通常会创建一个对象或模拟,设置属性/存根,然后调用操作,必要时传递一个params哈希。

例如(航空代码)

describe MyController do
  before(:each) do
    @project = mock_model(Project)
    Project.stub(:find_by_id) {@project}
    @batch = mock_model(Batch)
    Batch.stub(:new) {@batch}
  end

  it "should redirect to project_batch_url on success" do
    @batch.stub(:save) {true)
    post :create, :batch => { :some_key => :some_value }, :tasks => { :task_ids => [1,2,3] }
    response.should redirect_to(project_batch_url(@project,@batch))
  end

  it "should render :new on failure" do
    @batch.stub(:save) {false)
    post :create, :batch => { :some_key => :some_value }, :tasks => { :task_ids => [1,2,3] }
    response.should render_template("new")
  end
end

您可以在RSpec Rails docs中找到更多相关信息。

答案 1 :(得分:0)

使用BDD可帮助您定义界面。因此,如果您的控制器希望项目创建批处理并添加一些任务ID,那么“编写您希望的代码”。在控制器的实践中,这意味着尝试将逻辑推出控制器并进入模型。测试模型往往更直观,并且肯定比测试控制器更快。

以下是“mockist”观点中的一些可能的规范(未经测试):

# controller spec  
describe BatchesController do
  def mock_project(stubs={})
    @mock_project ||= mock_model(Project, stubs)
  end

  def mock_batch(stubs={})
    @mock_batch ||= mock_model(Batch, stubs)
  end

  context "POST create"
    it "calls #create_batch_and_add_tasks on the project"
      mock_project.should_receive(:create_batch_and_add_tasks).with(
        :batch => { :name => 'FooBatch' },
        :task_ids => [1,2,3,4]
      )
      Project.stub(:find).and_return(mock_project)

      post :create, :batch => { :name => 'FooBatch' }, :tasks => { :task_ids => [1,2,3,4] }
      # consider changing your params to :batch => { :name => 'FooBatch', :task_ids => [1,2,3,4] }
    end

    it "redirects to the project_batch_url on success" do
      mock_project(:create_batch_and_add_tasks => mock_batch(:save => true))
      Project.stub(:find) { mock_project }
      post :create, :these_params => "don't matter because you've stubbed out the methods"
    end

# controller
def create
  @batch = @project.create_batch_and_add_tasks(
             :batch => params[:batch],
             :task_ids => params[:tasks].try([:tasks_ids])
           )
  if @batch.save
    ...