使用gem对象作为实例变量的类的RSpec测试

掠夺者7

因此,我对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。

安迪

在RSpec中,“接收”是一种接受表示方法名称的符号的方法。(它允许您链接一个“ with”方法,该方法接受期望的参数列表。)要解决之前的问题,您可以这样做:

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

不过,这种绝对的丑陋暗示有些不对劲。是的。该代码严重违反了demeter定律,并且正在对其进行测试。

初次尝试清理它时,您可以考虑使用一种“缓存”调用@ instance_variable1.gemObjectMethod1的结果的方法。假设第一个方法返回了一组可枚举的小部件。您可以更改您的班级以包括以下内容:

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

private

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

您的班级仍然对gem对象了解得太多,但是现在您已经将其分解,可以重构查找小部件的方式-也许是其他gem或您自己的实现。出于测试目的,您可以通过模拟小部件将该决定与测试隔离。

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章