我真的很想学习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
部分..雅...整个事情:(
对不起这个新手问题 - 希望你们能帮助或至少指出我正确的方向:)
由于
答案 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
...