2016-09-29 210 views
-1

我有一个问题,我一直在打我的头,反对了几个小时,而且我也没有人问我已经能够上来了有一个合适的答案。如何测试一个以集装箱方式修改另一个类的属性的类方法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的东西!

回答

1

我认为这个问题是have_received(working = true),它应该是have_received(:working=).with(true)

编辑:使用have_received

例子

这对我的作品

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 
+0

哇,谢谢!那么,这只是我使用间谍语法时的一个错误,或者这与我所尝试的方法不同? – LMCMLJ

+1

@LMCMLJ是的,我认为这只是使用错误的语法。我添加了几个链接到我的答案,它演示了'have_received'的用法 – Rashmirathi

0

如果你宁愿只是避免磕碰,你可以使用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 
相关问题