- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想在下面的代码中测试对obj.my_method
的条件调用:
def method_to_test(obj)
# ...
obj.my_method if obj.respond_to?(:my_method)
# ...
end
obj
可以是a
Foo
或a
Bar
。一个实现
my_method
,另一个不:
class Foo
def my_method; end
end
class Bar
end
describe '#method_to_test' do
context 'when obj is a Foo' do
let(:obj) { instance_double('Foo') }
it 'calls my_method' do
expect(obj).to receive(:my_method)
method_to_test(obj)
end
end
context 'when obj is a Bar' do
let(:obj) { instance_double('Bar') }
it 'does not call my_method' do
expect(obj).not_to receive(:my_method) # <- raises an error
method_to_test(obj)
end
end
end
obj
是一个未实现
my_method
的验证双精度数:
#method_to_test
when obj is a Foo
calls my_method
when obj is a Bar
does not call my_method (FAILED - 1)
Failures:
1) #method_to_test when obj is a Bar does not call my_method
Failure/Error: expect(obj).not_to receive(:my_method)
the Bar class does not implement the instance method: my_method
obj
是一个验证双?
verify_partial_doubles
,因此将
instance_double('Bar')
更改为
object_double(Bar.new)
或只是
Bar.new
没有帮助。
最佳答案
有趣又棘手的问题!从rspec文档中,我发现:
[编辑:刚刚看到您已经了解rspec抱怨的原因,所以您可以跳到可能脏/不太脏的解决方案部分我会保留我在这里找到的解释,以防其他人面临类似的问题(请纠正我/添加进一步的信息!)]
验证实例加倍不支持类报告不存在的方法
因为需要对类的实际实例进行验证。这通常是
使用方法缺少的情况。
-https://relishapp.com/rspec/rspec-mocks/docs/verifying-doubles/dynamic-classes
文件中提到了instance_double和method_missing的使用问题,但我相信这和你面临的问题是一样的。你的bar类没有报告响应:my_method。事实上,在失败的测试中,method_to_test(obj)
永远不会被调用,因为当您试图定义实例的期望值时,测试失败了:
describe '#method_to_test' do
context 'when obj is a Bar' do
let(:obj) { instance_double('Bar') }
it 'does not call my_method' do
puts "A"
expect(obj).not_to receive(:my_method) # <- raises an error
puts "B" # <- never runs
method_to_test(obj)
end
end
end
#method_to_test
when obj is a Bar
A
does not call my_method (FAILED - 1)
:my_method
,并且无法预防地认为它实际上帮助您识别测试中的问题(毕竟,您试图在不存在的东西上添加方法调用期望),所以很可能是打字错误,对吧-哎哟!)是的。
:my_method
,这样就可以添加消息期望,但随后您必须在Bar的上下文中重新定义
respond_to?
,结果如下:
def my_method
raise # should never be executed in any case
end
def respond_to?(m_name)
m_name != :my_method && super(name)
end
method_to_test(obj)
不会因为bar实例上缺少方法而引发异常。你可以这样做:
describe '#method_to_test' do
context 'when obj is a Bar' do
let(:obj) { instance_double('Bar') }
it 'does not call my_method' do
expect { method_to_test(obj) }.not_to raise_error
end
end
end
NoMethodError
时失败。你可以试试这个,但不行:
it 'does not call my_method' do
expect { method_to_test(obj) }.not_to raise_error(NoMethodError)
end
:my_method
时引发的错误不是
NoMethodError
类型,而是
RSpec::Mocks::MockExpectationError
类型:
#method_to_test
when obj is a Bar
does not call my_method (FAILED - 1)
Failures:
1) #method_to_test when obj is a Bar does not call my_method
Failure/Error: expect { method_to_test(obj) }.not_to raise_error
expected no Exception, got #<RSpec::Mocks::MockExpectationError: #<InstanceDouble(Bar) (anonymous)> received unexpected message :my_method with (no args)> with backtrace:
RSpec::Mocks::MockExpectationError
而不是
NoMethodError
来实现预期,但这也会创建脆弱的测试:如果您将测试条实例更改为一个真正的obj而不是一个instance-double,那么如果调用
NoMethodError
会提高
:my_method
?这项测试将继续通过,而根本不测试任何有价值的东西此外(如注释中指出的),如果您这样做,RSPEC将警告您:
respond_to?
通常表示您缺少在这些多个类中定义和实现的适当接口。我无法帮助您了解重构的细节,因为这将高度依赖于您当前的代码上下文/实现细节但是,您应该评估它是否值得花费,如果不值得,我建议将
obj.my_method if obj.respond_to?(:my_method)
提取到一个专用的方法调用中,这样断言它不会引发_error将是一个更可靠的断言,因为您可以在较少的上下文中引发奇怪的异常此外,如果这样做,您可以传递一个简单的
double
对象,该对象将允许您按照最初预期的方式添加消息期望。
关于ruby - 如何在RSpec中使用验证 double 设置否定消息期望?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34920134/
我想知道 Rspec 中的命令式和声明式步骤是什么。 这是 Rspec 书中的示例代码: Scenario: transfer money (declarative) Given I have $10
我正在尝试使用 Travis 设置 CI。但是我遇到了在 Travis 上失败但在本地没有的测试,甚至提供了相同的种子。 我认为种子运行相同,但现在我不确定,并想弄清楚它是否存在,所以我现在在哪里看。
RSpec 的文档提到了 --bisect option ,当运行时提供最小的复制,例如 rspec ./spec/calculator_10_spec.rb[1:1] ./spec/calculat
我有一些昂贵的测试设置,仅对我的规范中的少数示例是必需的,如果需要,它只需要运行一次。因为它很慢,所以我试图避免将它放在 before(:each) block 中,但 before(:all) 似乎
在我的 Gemfile 中 gem 'rspec-rails', '~> 3.3' 我发现,errors_on 匹配器移动到了另一个 gem:https://github.com/rspec/rspe
如果我运行此命令“rspec ./spec/requests/api/v1/password_reset_request_spec.rb”,此文件中的所有测试都会通过。 但是,当我运行“rspec”时
我花了 4 天时间尝试正确安装 Ruby on Rails,但我遇到了一个大问题。我第一次使用Linux(对我来说更舒服),但遇到问题后,我使用了Windows。令我惊讶的是,我在 Windows 上
我在这样的验证中测试了很多坏字符串: ['0', '3:a', 'xx:11', '-1', '-3:00', 'h', 'h2', 'h2h', 'm', 'm10', 'm10m', '2hm',
我的测试套件中有一部分运行着一堆非常慢的导入器。这些测试不需要经常运行(除非实际上正在处理导入器)所以我使用 Rspec 标签将它们分开:http://relishapp.com/rspec/rspe
Rspec 尝试在运行任何规范文件或整个测试套件结束时运行 Test::Unit 测试。它仍然没关系,因为我没有任何测试单元测试文件,但它尝试传递给 rspec 的命令行选项,因为它们将传递给 Tes
我有一段代码要测试: class User :destroy end 请举例测试关联代码的RSpec代码。 最佳答案 对我来说,这个变体效果很好: describe User do it { s
我正在尝试在 rails Controller 规范中重用一些通用代码。我对管理员用户和普通用户有不同的上下文。但是,对于特定操作,大部分行为是相同的,因此我尝试将这种常见行为提取到辅助函数中: de
我有两个类OneClass和 AnotherClass : class OneClass def initialize(*args) @another_member = AnotherCl
我有一个看起来像这样的模型: class Gist def self.create(options) post_response = Faraday.post do |request|
我是 RSPEC 的新手。我编写了一个名为 result_spec.rb 的 RSPEC 代码,如下所示: describe '#grouped_scores' do subject { result
我对字符串类进行了如下扩展: class String def last_character self[-1] end end 我将 string.rb 文件放在 lib 中,如下所示
我是 RSpec 的新手,我在其中编写了一个测试场景: my_object.should_not be_valid 它工作正常。但是,我想测试模型的特定属性是否无效。这样的 RSpec 行为是现成的吗
我正在尝试测试邮政编码属性的长度以确保其长度为 5 个字符。现在我正在测试以确保它不是空白,然后是 4 个字符太短,6 个字符太长。 有没有办法测试它是否正好是 5 个字符?到目前为止,我在网上或 r
我将rspec与电子邮件规范gem一起使用。我正在尝试做: last_delivery = ActionMailer::Base.deliveries.last last_delivery.body.
我创建了一个新的 rails 应用程序,并按照此处的 rspec-rails 安装说明进行操作 - https://github.com/rspec/rspec-rails然后我在我的 app/lib
我是一名优秀的程序员,十分优秀!