在编写底层Model类之前编写Controller测试和类是否可能(也是合理的)?我以为我看到了如何做到这一点的笔记,但现在我找不到食谱了。
例如,请考虑以下控制器:
# file: app/controllers/premises_controller.rb
class PremisesController < ApplicationController
def create
@premise = Premise.new(params[:premise])
respond_with @premise
end
end
我可以在创建基础Premise模型和前提之前测试此控制器代码吗?我知道以下内容不起作用 - 你会如何重写它(如果可能的话)?
# file: spec/controller/premise_spec.rb
require "spec_helper.rb"
describe PremisesController do
context 'POST create' do
it 'should assign a new Premise to @premise' do
premise = stub_model(Premise)
Premise.stub(:create) { premise }
post :create
assigns(:premise).should == premise
end
end
end
end
我越是想到它,我越相信我做需要定义Premise
类 - PremisesController
代码需要引用它。所以我将我的问题改为“是否有必要创建基础premises
数据库表以运行PremisesController
测试?”
此时,我看不到一个好方法(不改变PremisesController
代码,这会破坏测试点)。例如,对respond_with
的调用调用@premise.has_errors?
,后者又访问数据库以获取列名。除非我愿意将ActiveRecord
内部的方法存根,否则我不会看到如何避免对数据库的命中。
但是我很乐意以其他方式表现出来。
答案 0 :(得分:0)
我还没有测试过这段代码,但很确定它应该可行。你现在可以这样做: 只是一个开始,但如果你愿意,你可以尝试这样的事情,虽然改变你的代码可能是不好的做法只是为了传递规格。
class PremisesController < ApplicationController
def create
@premise = premise_until_model_finished params[:premise]
respond_with @premise
end
def premise_until_model_finished premise
Premise.new premise
end
end
require "spec_helper.rb"
describe PremisesController do
context 'when creating a premise' do
before :each do
@my_fake_model = {
:some_attribute => 'funk',
:some_other_attribute => 'a-delic'
}
PremisesController.any_instance.stub( :premise_until_model_finished).and_return(
@my_fake_model
)
PremisesController.any_instance.should_receive(
:premise_until_model_finished
).and_return( @my_fake_model )
post :create
end
it 'should create a premise as expected' do
# your criteria here...
end
end
end
答案 1 :(得分:0)
好的 - 我已经平静下来了:除非数据库表存在,否则创建任何有意义的测试都是不切实际的 - ActiveRecord的太多位依赖于定义表。
但这并不妨碍在控制器和模型之间进行清晰分离的编写测试。 dchelimsky自己在this RSpec issue中雄辩地阐述了这一点。他的帖子的主旨是:
get
并验证生成的json响应。顺便说一句,我真的建议阅读David的帖子 - 他会带你逐步完成一个步骤,解释每一步背后的理念和推理。