I have an issue I have been whacking my head against for hours now, and neither I nor anyone I have asked has been able to come up with a suitable answer.
Essentially, I am writing a method that allows me to edit an instance variable of another method. I have multiple ways of doing this, however my issue is with writing the test for this method. I have tried many different double types, however as they are immutable and do not store states, I did not manage to find a way to make it work.
Here is the class whose working
variable is changed:
class MyClass
attr_writer :working
def working?
@working
end
end
Here is the class and method that change it:
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
(The actual class is much larger, but I have only included a generalised version of the method in question. I can put all of the specific code up in a gist if it would help)
So I need a way to test that makes_work
does in fact accept the array of objects to be changed, changes them and appends them to array_of_fixed_objects
. What would be the best way of testing this in a containerised way, without requiring MyClass?
My last attempt was using spies to see what methods were called on my dummy instance, however a range of failures, depending on what I did. Here is the most recent test I wrote:
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
This currently throws the error:
undefined method to_sym for true:TrueClass
Many thanks for any help! I apologise if some formatting/ info is a little bit messed up, I am still pretty new to this whole stackoverflow thing!
I think the problem is have_received(working = true)
, it should be have_received(:working=).with(true)
Edit:
Examples of using have_received
This works for me
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