Ruby on rails Rspec:控制器中的存根方法
我可以知道如何创建控制器创建方法中的存根方法吗?我需要为此编写规范,但我遇到了这些错误。我需要检查controller中的create方法,在模型中创建新的公司记录之前,必须执行validate_fbid方法 错误:Ruby on rails Rspec:控制器中的存根方法,ruby-on-rails,rspec,ruby-on-rails-3.2,mocking,stub,Ruby On Rails,Rspec,Ruby On Rails 3.2,Mocking,Stub,我可以知道如何创建控制器创建方法中的存根方法吗?我需要为此编写规范,但我遇到了这些错误。我需要检查controller中的create方法,在模型中创建新的公司记录之前,必须执行validate_fbid方法 错误: 1) Companies new company create with valid information#validate_fbid should have correct parameters and return value Failure/Error: Companie
1) Companies new company create with valid information#validate_fbid should have correct parameters and return value
Failure/Error: CompaniesController.create.should_receive(:validates_fbid).with(company)
NoMethodError:
undefined method `create' for CompaniesController:Class
# ./spec/requests/companies_spec.rb:38:in `block (5 levels) in <top (required)>'
2) Companies new company create with valid information#validate_fbid should fbid validation passed
Failure/Error: CompaniesController.create.stub(:validates_fbid).and_return('companyid')
NoMethodError:
undefined method `create' for CompaniesController:Class
# ./spec/requests/companies_spec.rb:43:in `block (5 levels) in <top (required)>'
请求/公司\u spec.rb
context "#validate_fbid" do
#validate fbid
let(:company){ Company.new(name:'Example Company', url: 'www.company.com', fbid: 'companyid', desc: 'Company desc' )}
it "should have correct parameters and return value" do
CompaniesController.create.should_receive(:validates_fbid).with(company)
.and_return('companyid')
end
it "should fbid validation passed" do
CompaniesController.create.stub(:validates_fbid).and_return('companyid')
company.fbid.should_not be_nil
company.fbid.should == 'companyid'
company.save
expect { click_button submit }.to change(Company, :count).by(1)
end
end
当方法是测试用例的主题时,您不希望将其存根
context "#validate_fbid" do
#test the function here
#don't stub
end
在控制器中测试创建操作时,可以存根“validate_fbid”
希望能有所帮助。当代码很难测试时,通常是因为代码很复杂 您应该以以下方式重构此代码:
- 将验证逻辑转移到新的“服务类”中,该类在facebook上只负责公司验证
- 这将使验证功能独立于web层,并且更易于测试
- 为将单独测试此代码的服务类制定规范(无控制器)
- 清理控制器的逻辑-您不希望控制器中有逻辑(经验法则:嵌套最大值的一个级别)
- 控制器的规格也会更简单
def create
company = Company.new(params[:company])
verified = FbCompanyVerifier.new.verify(company)
if verified and company.save
# success logic
else
# fail logic
end
end
如果您正在测试控制器,则可以直接访问控制器:
controller.stub(:message) { 'this is the value to return' }
以下是Rspec 3(3.3)的推荐语法:
允许(CompaniesController.)的任何实例接收(:验证fbid)并返回(“companyid”)
期望(CompaniesController.)的任何实例接收(:验证fbid)并返回(“companyid”)
资料来源:Hi,感谢您的回复。这是否意味着我需要创建一个具有“new”方法和“verify”方法的类FbCompanyVerifier?我想我不允许在控制器页面中创建类,所以我应该创建哪个文件夹“FbCompanyVerifier”?谢谢你的澄清。我对此非常陌生。正确-一个完整的类,实例方法为“verify”,如果“new”(initialize)方法没有任何作用,您可以跳过它。通常这是一种最佳实践,因此您可以使用一流对象/普通ruby对象。(有些可能将类与类方法一起使用,这有其自身的优点和缺点)。由于该类依赖于您的模型公司,因此您应该将其放在应用程序文件夹“app/services”中的某个位置。您可以将包含一两个方法的独立于web层的小型单责任类放在其中。您还可以查看code_climate博客文章,该文章描述了类似的重构—将逻辑代码提取到具有单责任的新类中,编写简单的规范,然后将其用作PORO(普通的旧ruby对象)在代码中…:如果
FbCompanyVerifier#verify
执行HTTP请求(或您希望在测试期间避免的任何其他副作用),您如何测试以防止它?在FbCompanyVerifier
上使用allow\u any\u instance\u of
?allow\u any\u instance\u of(CompaniesController)。接收(:validates\u fbid)。并返回rspec3的('companyid')
。这个答案对我有效,因为当我存根该方法时,我知道它需要一个参数,但我不知道参数是什么。我只想传递参数,所以我使用带有参数的块来重写(存根)方法。
def create
company = Company.new(params[:company])
verified = FbCompanyVerifier.new.verify(company)
if verified and company.save
# success logic
else
# fail logic
end
end
controller.stub(:message) { 'this is the value to return' }