Rspec期望调用分配(=)方法

Posted

技术标签:

【中文标题】Rspec期望调用分配(=)方法【英文标题】:Rspec expect assignment (=) method to be called 【发布时间】:2014-03-03 17:46:14 【问题描述】:

我正在编写一些测试,我想断言某些方法实际上调用了我已存根的对象上的赋值方法。

我试过这样做:

expect(test_object.some_object[:whatever]).to receive(:=).with(some_data) #Does NOT work

test_object.method()

这似乎不起作用。我有办法做到这一点吗?


这样做的原因是“some_object”是一个开放的结构对象,它是我不想在测试时调用的外部库的替身。

【问题讨论】:

【参考方案1】:

Ruby 中没有“赋值方法”之类的东西。当您在 Ruby 中为变量(例如局部变量、实例变量、类变量)赋值时,您并没有调用方法。变量是对象的某种“容器”,RSpec 无法跟踪是否发生了对变量的赋值。

此规则的一个例外是所谓的“setter”方法,与attr_writerattr_accessor 一起使用。在这种情况下,您本身仍然没有赋值方法,但是如果您定义了一个方法,例如:

class MyObject
  def my_attribute=(value)
    ...
  end
end

或使用等效的attr_... 调用,然后使用以下代码:

MyObject.new.my_attribute = 'foo'

将被视为

MyObject.new.my_attribute=('foo')

您可以像任何其他方法一样对my_attribute= 方法设置存根或设置期望值。

【讨论】:

我的印象是赋值运算符和其他运算符(如 +、- 和 *)都是方法的简写。也许我误解了。你有什么好的参考资料可以让我读到这个吗? (要明白我的意思,请看这里:http://ruby.about.com/od/oo/ss/Overloading-Operators.htm) 虽然很多运算符都变成了方法调用,但赋值运算符是一个例外,如您提供的参考资料中所述。 好吧,我去。奇怪的是,当我查看它时,我没有看到它。无论如何,谢谢。我认为我最好的解决方案是制作一个包装外部库的 setter 和 getter 方法。【参考方案2】:

可以验证实例变量赋值:

# checks @whatever
expect(assigns(test_object.some_object[:whatever])).to eq(some_data)
test_object.method()

【讨论】:

以上是关于Rspec期望调用分配(=)方法的主要内容,如果未能解决你的问题,请参考以下文章

rspec 测试时,ActionMailer 方法调用在模块中返回 nil

当方法被意外调用的次数超过指定次数时,有没有办法从 rspec 获取堆栈跟踪?

RSpec控制器测试 - 空白响应.body

RSpec 控制器测试 - 空白 response.body

RSpec:期望更改多个

Ruby Rspec 对捕获的异常的消息期望