将应用程序(正在进行)升级到 3.1 后,我不得不更改清除密码和密码确认字段的测试。我必须测试缺失值属性,而不是测试空值属性。
那很好,但是当我去关闭字段清除以使测试失败时,它仍然通过,因为字段仍然被清除(值仍然丢失)。以前,如果用户创建失败,我在适当的控制器中创建了几行来清除字段(因此在重新显示表单时字段将为空)。现在看来已经没有必要了。
现在是密码和确认字段的默认行为吗?
我正在使用rspec-spies,并且想知道是否有一种方法可以在完成所有呼叫后检查间谍。
例如,如果我做类似的事情
# setup
Post.stub(:find).with(@post.id).and_return(@post)
do_something_to_call_post_find()
# verify find was called
Post.should have_received(:find).with(@post.id)
Run Code Online (Sandbox Code Playgroud)
这很好用,但如果 Post没有收到预期的参数,我会收到一条无用的错误消息(基本上是“Post 应该收到带有 123 的 find”)。相反,我想看看实际的调用是什么`find。
我可以在之后立即暂停do_something_to_call_post_find(),但是有没有办法列出对存根/间谍的所有调用/参数?
实际用例
今天这个用例让我着迷——我期望Post.should have_received(:find).with(@post.id),其中@post.id is an integer,我的控制器测试将参数(包括 id)作为字符串传递。如果我能够检查实际的调用,我就会看到123和之间的区别"123",而且它会很明显。
我在使用 Rspec 测试 Pundit 策略范围时遇到了障碍。基本上,我试图测试范围内的返回值是否严格限于用户。因此,我循环遍历为用户返回的所有问题,并确保 id 等于用户。
这是绿色的,但是当它是非公民角色时它会失败,因为 Scope 调用仅返回一个 Issue 对象。这不是什么大问题,因为每个角色都有一个 .where() 的范围,但这是一种代码味道,我可能做错了一些事情。
我有一个执行该操作的 IssueController
class IssuePolicy < ApplicationPolicy
class Scope < Struct.new(:user, :scope)
def resolve
if user.role == 'citizen'
scope.where(:user_id => user.id)
else
scope
end
end
end
Run Code Online (Sandbox Code Playgroud)
为了在 rspec 中测试这一点,我必须这样做
require 'spec_helper'
describe IssuePolicy do
before(:each) do
@user = FactoryGirl.create(:user)
@issue = FactoryGirl.create(:issue)
@last_issue = FactoryGirl.create(:issue, user_id: User.last.id + 1)
end
context "for a citizen" do
before(:each) do
@user.update(role: 'citizen')
end
it "should only return their posts on …Run Code Online (Sandbox Code Playgroud) 我在学习 Codeschool 课程时正在做一些测试rspec,但我不知道如何使用expect语法编写模型验证是否存在。如果我写:
expect(user).should_not be_valid
Run Code Online (Sandbox Code Playgroud)
rspec告诉我使用expect而不是should_not. 但我找不到如何编写正确的表达式来检查验证。
对于如何编写 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方法
假设我已经按照以下方式定义了 Ruby 类:
class Blah
def self.ref_class
::Other::Thing
end
end
Run Code Online (Sandbox Code Playgroud)
.ref_class返回一个类引用(这就是它的名字,对吧?)。如何使用 RSpec 测试此方法?
我正在尝试为 API 控制器编写简洁的测试,但我在使用 RSpec 提供的“单行”语法时遇到了问题。
我明确地覆盖主题以引用发布操作而不是控制器:
let (:params) { some_valid_params_here }
subject { post :create, params }
Run Code Online (Sandbox Code Playgroud)
当我使用单行语法来测试 http_status 时,它工作正常:
it { is_expected.to have_http_status(:created) }
# pass!
Run Code Online (Sandbox Code Playgroud)
但当我尝试将它用于不同的期望时,它爆炸了:
it { is_expected.to change{SomeActiveRecordModel.count}.by(1) }
# fail! "expected result to have changed by 1, but was not given a block"
Run Code Online (Sandbox Code Playgroud)
值得注意的是,当我以更长的形式运行第二个期望时,明确地调用主题,它起作用了:
it "creates a model" do
expect{ subject }.to change{SomeActiveRecordModel.count}.by(1)
end
# pass
Run Code Online (Sandbox Code Playgroud)
这是否只是单行语法的一个弱点,它无法处理这个更复杂的表达式?或者我是否误解了如何将主题推断到这些测试中?
(注意:我知道将主题设置为一个动作会有一些批评者,我很高兴听到意见,但这不是这个问题的目的)。
我在 rails 5 中有一个小应用程序。我尝试使用 Rspec 来测试它,但使用只读模型失败了。
我有只读模型 Product 和普通模型 ProductMsp。第二个 a 是与 Product 关联的所有价格的列表,并存储在 Rails DB 中。产品是与另一个数据库的外部只读连接,用于撤消产品列表。
我将与产品的关联添加到 spec/factories/product_msps.rb。
FactoryGirl.define do
factory :product_msp do
product_id 11
initial_date '01-01-2017'
expiry_date '31-01-2017'
msp 9999.99
association :product
end
end
Run Code Online (Sandbox Code Playgroud)
我没有添加任何新的测试。当我再次运行 rspec 时,我遇到了失败。可能 rspec 想要创建产品,但由于只读数据库表而无法创建。
Failures:
1) ProductMsp Validations initial_date cannot by empty
Failure/Error: pm = FactoryGirl.build(:product_msp, initial_date: nil)
ActiveRecord::ReadOnlyRecord:
Product is marked as readonly
# ./spec/models/product_msp_spec.rb:17:in `block (3 levels) in <top (required)>'
Run Code Online (Sandbox Code Playgroud)
下面是失败的测试:(还有更多的失败)
require 'rails_helper'
RSpec.describe ProductMsp, type: :model do
it 'initial_date cannot …Run Code Online (Sandbox Code Playgroud) 我目前正在开发 Rails 应用程序版本Rails 4.2.6和ruby 2.2.2. 我正在尝试运行 rspec 测试,我有版本
rspec-core 3.7.1
- rspec-expectations 3.7.0
- rspec-mocks 3.7.0
- rspec-rails 3.7.2
- rspec-support 3.7.1
Run Code Online (Sandbox Code Playgroud)
当我运行以下命令时bundle exec rspec spec/models/user_spec.rb,出现以下错误:加载 ./spec/models/user_spec.rb 时发生错误。
失败/错误:需要“rspec/rails”
NameError: 未初始化的常量 ActionView::Template::Handlers::ERB::ENCODING_FLAG
这是我的 rails_helper.rb
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
require "rspec/rails"
require "capybara/rspec"
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in …Run Code Online (Sandbox Code Playgroud) 我有一个 Rails 应用程序的 Rspec 测试
describe '.move_probes_to_master_list' do
let(:as) { create_list :a, 3, }
let(:bs) { create_list :b, 3 }
it 'sums the volumes' do
active_as= [as[1], as[2]]
b_ids = [2, 3]
expect_any_instance_of(A)
.to receive(:required_volume).twice.with(b_ids)
expect_any_instance_of(A)
.to receive(:update_move_to_master_list).twice
expect(A.calculate_volume(active_as)).to eq(true)
end
end
Run Code Online (Sandbox Code Playgroud)
基本上我调用A.calculate_volume并在这个类方法中,我想确保A该类的某个成员也收到一些其他消息。我不想删除这些方法,我希望它们正常运行,但我只想验证是否正在调用这些方法。
这是在循环中运行,所以我不确切知道我将处理哪些实例,但我想确保在某些成员(但不一定两次都必须是同一成员)上调用这两条消息A一共上课两次。
如果我删除expect_any_instance_of(A).to receive期望,一切运行正常并且测试通过。
如果我保留它们,方法调用将失败并且测试中断。
我尝试添加,and_call_original但我觉得我是在黑暗中拍摄,因为文档不清楚这些方法的实际操作方式。
那么如何验证某个类的实例是否在n不更改有关方法调用的其他任何内容的情况下收到消息时间?
我是否错过了在这里收到的期望?我不清楚为什么它首先会存根任何东西。