我是Rspec的新手,我正在尝试测试我的控制器方法的基本功能.我知道我不应该测试基本功能,但我更多的是为了学习而不是为了构建一些东西.
我有一个名为ProtocolsController的控制器.控制器用于基本CRUD功能.我正在尝试测试控制器#create方法.下面是我的#create控制器:
def create
@protocol = Protocol.new(protocol_params)
if @protocol.save
flash[:notice] = 'New protocol added'
redirect_back(fallback_location: 'test_results#index')
else
flash[:notice] = @protocol.errors[:name]
render 'new'
end
end
Run Code Online (Sandbox Code Playgroud)
为了测试悲伤路径,我想向控制器传递一个模拟对象,该对象包含用于创建Protocol类实例的必要参数.为此,我有以下代码:
describe '#create' do
it 'fails to save because the name already exists' do
params = FactoryGirl.attributes_for(:protocol)
post :create, :protocol => params
end
end
Run Code Online (Sandbox Code Playgroud)
现在我知道测试是不完整的,但我一次测试一行,当我运行Rspec时,我收到以下错误:
Failure/Error: post :create, :protocol => params
ArgumentError:
unknown keyword: protocol
Run Code Online (Sandbox Code Playgroud)
但是当我将帖子更改为: expect { post :create, :protocol => params }
有用.这让我想到了我的问题:
post :create, :protocol => params)失败了?任何对问题的见解都将非常感激.我一直在试图解决这个问题,我的猜测是,这是一个明显的答案.
我陷入了测试场景.
我有一个控制器方法:
def update
@object = Object.find params[:id]
# some other stuff
@object.save
rescue ActiveRecord::StaleObjectError
# woo other stuff
end
Run Code Online (Sandbox Code Playgroud)
第一部分我测试:
context '#update'
let(:object) { double }
it 'nothing fails' do
# some other stuff
expect(Object).to receive(:find).with('5').and_return(object)
expect(object).to receive(:save).and_return(true)
xhr :put, :update, id:5
expect(response).to be_success
expect(assigns(:object)).to eq(object)
end
end
Run Code Online (Sandbox Code Playgroud)
现在我想测试ActiveRecord::StaleObjectError异常.我想把它存根,但我找不到任何解决方法如何做到这一点.
所以我的问题是,如何提高ActiveRecord::StaleObjectErrorRSpec测试?
我试过这段代码,但它引发了错误: NameError: uninitialized constant RSpec::Mocks::Mock
RSpec::Mocks::Mock.stub(:i18n_scope).and_return(:activerecord)
model = double(:model, errors: double(:errors, full_messages: []))
ActiveRecord::RecordInvalid.new(model)
Run Code Online (Sandbox Code Playgroud)
我怎么能存根i18n_scope?
我正在使用RSpec(Rails 4.2.5 上的3.4 )测试视图。我在CRUD控制器中使用了decent_exposure gem。decent_exposure使得定义命名方法变得容易,这些命名方法可用于我的视图并记住结果值。
但是我不明白如何在视图规范中添加这些方法。我尝试根据RSpec文档进行操作,但是会引发错误。
为什么不起作用?如何article在视图中存根方法?
我的控制器
class Account::ArticlesController < Account::BaseController
expose(:articles) { current_user.articles }
expose(:article, attributes: :article_params)
# POST /account/articles
# POST /account/articles.json
def create
respond_to do |format|
if article.save
format.html { redirect_to account_article_url(article), notice: 'Article was successfully created.' }
format.json { render :show, status: :created, location: account_article_url(article) }
else
format.html { render :new }
format.json { render json: article.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /account/articles/1
# …Run Code Online (Sandbox Code Playgroud) 我们有一个用 RSpec 编写的单元测试套件。我们有一些失败的测试,实际上数量很多。
我正在寻找的是一个脚本或魔术命令,将所有失败的测试标记为已跳过,这样我就不必一一检查它们并将它们标记为已跳过。
我有一个自定义 RSpec 匹配器,用于检查作业是否已安排。它的使用方式如下:
expect { subject }.to schedule_job(TestJob)
日程表作业.rb:
class ScheduleJob
include RSpec::Mocks::ExampleMethods
def initialize(job_class)
@job_class = job_class
end
...
def matches?(proc)
job = double
expect(job_class).to receive(:new).and_return job
expect(Delayed::Job).to receive(:enqueue).with(job)
proc.call
true
end
Run Code Online (Sandbox Code Playgroud)
这对于正匹配来说效果很好。但它不适用于负匹配。例如:
expect { subject }.not_to schedule_job(TestJob) #does not work
为了使上述工作正常进行,该方法需要在未满足期望时matches?返回。false问题是,即使它返回 false,无论如何都会创建期望,因此测试会错误地失败。
关于如何使这样的事情发挥作用有什么想法吗?
我正在尝试在 Rspec 3.0 中使用 Spree 2.3 路由助手。在主应用程序中,我可以通过添加前缀来访问它们spree.,如下所示:
spree.admin_login_path => 'spree/admin/user_sessions#new'
Run Code Online (Sandbox Code Playgroud)
但是我似乎无法在 Rspec 中访问它们。
#rspec error
undefined local variable or method `spree_admin_login_path'
Run Code Online (Sandbox Code Playgroud)
我找到了在 rails_helper 文件中包含帮助程序的参考,但这会引发错误
# app/spec/rails_helper.rb
RSpec.configure do |config|
config.include Spree::Core::UrlHelpers
end
# configuring the above results in the following
app/spec/rails_helper.rb:21:in `block in <top (required)>': uninitialized constant Spree (NameError)
Run Code Online (Sandbox Code Playgroud)
如何访问$ rake routes测试中给出的狂欢路线?
对于如何编写 RSpec 3.2.x 规范来检查列表是否包含至少一个满足条件的项目,我有点不知所措。
下面是一个例子:
model = Invoice.new
model.name = 'test'
changes = model.changes
expect(changes).to include { |x| x.key == 'name' && x.value == 'test' }
Run Code Online (Sandbox Code Playgroud)
更改列表中也会有其他(自动)更改,因此我不想验证是否只有一个特定更改,而且我也不想依赖排序,expect(changes.first)...因此我基本上需要一种方法来至少指定列表中的一项更改满足条件。
我可以做这样的事情:
result = changes.any? { |x| x.key == 'name' .. }
expect(result).to eq(true)
Run Code Online (Sandbox Code Playgroud)
但是随后 rspec 失败不会给我任何有意义的输出,所以我认为必须有一种内置的方法来匹配它。
也欢迎有关如何构建测试的任何其他建议。
编辑:要清楚 - 更改是 ChangeObject 的列表,因此我需要访问它们的.key和.value方法
我有一个要在各个地方重复使用的主题块。
subject(:stubbed_data) do
expect(response.body).to eq(dynamic_var)
end
Run Code Online (Sandbox Code Playgroud)
dynamic_var对于不同的测试用例,变量将有所不同。有什么方法可以subbed_data用参数调用主题,以便为dynamic_var变量提供动态值?
这个问题与此不同:rspec Bisect Runs Indefinitely
\n\n我的测试套件需要 \xc2\xb1 10 分钟才能运行。\n当我运行时bundle exec rspec --bisect=verbose,它卡住了 1 个多小时(这是我等待的最长时间):
bundle exec rspec --bisect=verbose\nAssetSync: using /home/belasis/dev/deploy_webapp/config/initializers/asset_sync.rb\nBisect started using options: "" and bisect runner: :fork\nRunning suite to find failures...\nRun Code Online (Sandbox Code Playgroud)\n\n我点击后Ctrl C,出现此消息:
\n\nBisect aborted!\n\nThe most minimal reproduction command discovered so far is:\n (Not yet enough information to provide any repro command)\nRun Code Online (Sandbox Code Playgroud)\n\n因此,问题在于它没有运行任何内容并且没有给出错误消息。这怎么可能?
\n