2016-09-21 132 views
1

所以我对Rspec很陌生,我试图弄清楚如何编写一个将对象作为构造函数参数的类编写测试,并设置该对象是一个实例变量。然后在其他方法中调用该实例变量的对象方法。使用gem对象作为实例变量的类的RSpec测试

例子:

class ClassA 
    def initialize(string_object, gem_object) 
    @instance_variable1 = gem_object 
    @string = string_object 
    end 

    def check_validity?(some_arg) 
    unless @instance_variable1.gemObjectMethod1.gemObjectMethod2(some_arg).empty? 
     return true 
    end 
    false 
    end 
    .. 
    .. 
end 

我觉得怎么写这个规格很失落。对于一个我不明白什么指定一个构造函数实际需要。我意识到的是,我不得不找到某种方式来模仿或琢磨我作为参数获得的gem_object,但我不知道如何。

在接下来的方法,我已经试过这一点是:

describe '#check_validity?' do 
    context 'gets empty list' do 
    let (:actual) { subject.check_validity?("sample") } 
    before do 
     allow(subject).to receive(@instance_variable1.gemObjectMethod1.gemObjectMethod2).with("sample").and_return([]) 
    end 
    it 'returns false' do 
     expect(actual).to be false 
    end 
    end 
end 

但是这给了我的错误与我的构造说,预计2个论点,但被赋予0

任何帮助将非常感激!另外,我无法真正发现任何关于指定构造函数的参数。也许我正在寻找错误的地方,或者错过了一些明显的东西,因为这是我第一次使用BDD。

回答

1

在RSpec中,'receive'是接受表示方法名称的符号的方法。 (它允许您链“与”接受的参数预期的list方法。)要解决的,你可以做到这一点前块:

before do 
    allow(subject.instance_variable_get(:@instance_variable1).gemObjectMethod1).to receive(:gemObjectMethod2).with("sample").and_return([]) 
end 

的是纯粹的丑陋,不过,顾名思义东西错误。它是。该代码违反law of demeter相当糟糕,测试正在被吸收。

作为第一次尝试清理它,您可能会考虑一种方法来“缓存”调用@ instance_variable1.gemObjectMethod1的结果。假设第一个方法返回一个可枚举组件。你可以改变你的类包括这样的事情:

def check_validity(a_string) 
    widgets.gemObjectMethod2(a_string).empty? 
end 

private 

def widgets 
    @widgets ||= @instance_variable1.gemObjectMethod1 
end 

你的类仍然知道有点太多关于宝石的对象,如今却以这样的方式打破下来,你可以重构你是怎么找到小部件 - 也许是一个不同的宝石或你自己的实现。为了您的测试目的,您可以通过嘲讽小部件来将该决定从测试中分离出来。

let(:gem_widgets) do 
    instance_double(GemObjectMethod1ResultClass, gemObjectMethod2: true) 
end 

before do 
    allow(subject).to receive(:widgets).and_return(gem_widgets) 
    allow(gem_widgets).to receive(:gemObjectMethod2).with("sample"). 
    and_return([]) 
end 

it 'should pass with "sample"' do 
    expect(actual).to eql true 
end 
+0

谢谢,这很有帮助。你有关于如何测试构造函数的建议吗?我正在考虑在调用new之前测试一个对象不存在,然后它执行并且它具有正确的实例变量。我对如何测试对象是否已经创建了空白。 – marauder7

+0

我经常用类似这样的类做的是通过属性读取器(例如attr_reader:string_object,:ClassA顶部的gem_object)提供实例变量。如果你这样做,那么测试任务是非常简单的 - 在实例化后检查getter方法的值。 – AndyV

+0

谢谢。我确实有一个问题。通过创建小部件方法,我不需要确切地找出gemObjectMethod1返回的内容,是否违背抽象原则? – marauder7

相关问题