如何测试一个以集装箱方式修改另一个类的属性的类方法rspec
问题描述:
我有一个问题,我一直在打我的头,反对了几个小时,而且我也没有人问我已经能够上来了有一个合适的答案。如何测试一个以集装箱方式修改另一个类的属性的类方法rspec
本质上,我写了一个方法,允许我编辑另一个方法的实例变量。我有多种方式来做这件事,但是我的问题是为这种方法编写测试。我尝试了许多不同的双重类型,但是因为它们是不可变的,并且不存储状态,所以我没有设法找到使其工作的方法。
下面是其working
变量改变类:
class MyClass
attr_writer :working
def working?
@working
end
end
下面是改变它的类和方法:
class OtherClass
def makes_work
@ary_of_instances_of_MyClass_to_fix.map do |x|
x.working = true
@ary_of_fixed_objects << x
end
end
end
(实际的类大得多,但我只有包括一个广义版本的方法,如果有帮助,我可以把所有的具体代码放在要点中)
所以我需要一种方法来测试makes_work
实际上接受要更改的对象数组,更改它们并将它们附加到array_of_fixed_objects
。无需MyClass,以容器化的方式测试这种方法的最佳方式是什么?
我最后一次尝试使用间谍来查看在我的虚拟实例上调用了哪些方法,但是根据我做了什么,发生了一系列失败。下面是最近的测试中,我写道:
describe '#make_work' do
it 'returns array of working instances' do
test_obj = spy('test_obj')
subject.ary_of_instances_of_MyClass_to_fix = [test_obj]
subject.makes_work
expect(test_obj).to have_received(working = true)
end
end
目前这引发错误:
undefined method to_sym for true:TrueClass
任何帮助,非常感谢!我很抱歉,如果一些格式/信息有点混乱,我仍然很新的整个stackoverflow的东西!
答
我认为这个问题是have_received(working = true)
,它应该是have_received(:working=).with(true)
编辑:使用have_received
- https://github.com/rspec/rspec-mocks#test-spies
- https://relishapp.com/rspec/rspec-mocks/v/3-5/docs/setting-constraints/matching-arguments
例子
这对我的作品
class MyClass
attr_writer :working
def working?
@working
end
end
class OtherClass
attr_writer :ary_of_instances_of_MyClass_to_fix
def initialize
@ary_of_fixed_objects = []
end
def makes_work
@ary_of_instances_of_MyClass_to_fix.map do |x|
x.working = true
@ary_of_fixed_objects << x
end
end
end
describe '#make_work' do
subject { OtherClass.new }
it 'returns array of working instances' do
test_obj = spy('test_obj')
subject.ary_of_instances_of_MyClass_to_fix = [test_obj]
subject.makes_work
expect(test_obj).to have_received(:working=).with(true)
end
end
答
如果你宁愿只是避免磕碰,你可以使用OpenStruct的一个实例,而不是一个双重的:
class OtherClass
attr_writer :ary_of_instances_of_MyClass_to_fix
def initialize
@ary_of_instances_of_MyClass_to_fix, @ary_of_fixed_objects = [], []
end
def makes_work
@ary_of_instances_of_MyClass_to_fix.map do |x|
x.working = true
@ary_of_fixed_objects << x
end
@ary_of_fixed_objects
end
end
require 'ostruct'
RSpec.describe "#makes_work" do
describe "given an array" do
let(:array) { [OpenStruct.new(working: nil)] }
subject { OtherClass.new }
before do
subject.ary_of_instances_of_MyClass_to_fix = array
end
it "sets the 'working' attribute for each element" do
expect(array.map(&:working)).to eq [nil]
subject.makes_work
expect(array.map(&:working)).to eq [true]
end
end
end
哇,谢谢!那么,这只是我使用间谍语法时的一个错误,或者这与我所尝试的方法不同? – LMCMLJ
@LMCMLJ是的,我认为这只是使用错误的语法。我添加了几个链接到我的答案,它演示了'have_received'的用法 – Rashmirathi