Ruby RSpec-如何测试不同的类';方法被调用了吗?
我想对一个String#select方法进行修补,并想创建一个测试套件来检查它是否使用Array#select 我尝试创建一系列测试,使用Ruby RSpec-如何测试不同的类';方法被调用了吗?,ruby,testing,rspec,Ruby,Testing,Rspec,我想对一个String#select方法进行修补,并想创建一个测试套件来检查它是否使用Array#select 我尝试创建一系列测试,使用不接收,同时使用不接收(数组:选择)和不接收(:选择)。我还尝试使用数组(string.chars)代替字符串。Google和stack overflow没有给出答案 describe "String#select" do it "should not use built-in Array#select" do string = "HELLOwor
不接收,同时使用不接收(数组:选择)
和不接收(:选择)
。我还尝试使用数组(string.chars)代替字符串。Google和stack overflow没有给出答案
describe "String#select" do
it "should not use built-in Array#select" do
string = "HELLOworld".chars
expect(string).to_not receive(Array:select)
end
end
预期:一个工作测试套件,用于检查整个方法中是否未使用Array#方法
实际输出:我得到一个错误,没有使用足够的参数。输出日志如下:
1) RECAP EXERCISE 3 Proc Problems: String#select should not use built-in Array#select
Failure/Error: expect(string).to_not receive(Array:select)
ArgumentError:
wrong number of arguments (given 0, expected 1..4)
# ./spec/problems_spec.rb:166:in `select'
# ./spec/problems_spec.rb:166:in `block (4 levels) in <top (required)>'
1)回顾练习3过程问题:字符串#选择不应使用内置数组#选择
失败/错误:预期(字符串)。不接收(数组:选择)
参数错误:
参数数量错误(给定0,应为1..4)
#./spec/problems_spec.rb:166:in'select'
#./spec/problems_spec.rb:166:in'block(4层)in'
首先:测试应该检查调用的方法的结果,而不是它们的实现方式。过分依赖这一点会给你带来麻烦
但这样做可能有正当的理由,但仔细想想,你可以用另一种方式来测试:
假设String#select
在内部使用Array#select
,后者在某些情况下是有缺陷的。最好做一个测试,以一种触发bug的方式设置宇宙,并检查bug行为是否不存在。然后修补字符串#选择
并使测试呈绿色。这是一种更好的方法,因为测试现在告诉每个人为什么不应该在内部使用Array#select
。如果bug被移除,那么移除补丁并检查规范是否仍然是绿色的是最简单的事情
也就是说,如果您仍然需要,您可以使用
的任何实例来完成,例如,此规范将失败:
class String
def select(&block)
split.select(&block) # remove this to make the spec pass
end
end
specify do
expect_any_instance_of(Array).not_to receive(:select)
'foo'.select
end
如果您不想使用
()的任何实例,可以临时覆盖类中的方法以使其失败:
class String
def select(&block)
#split.select(&block)
end
end
before do
class Array
alias :backup_select :select
def select(*)
raise 'No'
end
end
end
after do
class Array
alias :select :backup_select # bring the original implementation back
end
end
specify do
expect { 'foo'.select }.not_to raise_error
end
恢复原始实现时需要使用别名,这样就不会弄乱在这一次之后运行的规范
但你可以看到这种方法是多么复杂和混乱
无论如何,你想要达到的目标很可能是一个设计问题,但是如果没有更多的细节就很难说了 你怎么能让修补程序数组不响应
select
?你不能用方法内省来检查“mystring”.method(:select).source\u位置
指向包含monkeypatch的模块吗?