【问题标题】:RSpec test if a function was calledRSpec 测试是否调用了函数
【发布时间】:2014-12-15 01:46:29
【问题描述】:

我是 RSpec 的新手,正在深入研究。我希望测试一些琐碎的功能只是为了熟悉 RSpec DSL。所以,直截了当:我将如何使用 RSpec 的 3.1.7 语法测试以下代码片段?更具体地说,我如何测试一个函数是否被调用?


代码:

manipulate_loc(loc, op, n)
    x = loc.x.send(op, n)
    y = loc.y.send(op, n)
    yield x, y
end

def scale_up(loc, n)
    manipulate_loc(loc, :*, n)
end

测试:

it 'can scale up Locations' do
    expect(scale_up(subject,2)).to receive(:manipulate_loc).with(subject, 2)
end

我知道这是一个奇怪的例子,因为我正在传递块,但是没有块的 ruby​​ 会是什么!

【问题讨论】:

  • 与测试无关,但你在哪里传递块? manipulate_loc(loc, :+, n) 不发送块,因此 yield 应该在此代码中失败。
  • @Amadan 你是对的,operated_loc 会产生一个块,而不是通过它......我对 Ruby 块的掌握仍然模糊,但它不会失败。它可以像这样使用:operated_loc(loc, :+, n){|x,y| ...},一切正常。我正在尝试使用块来操作 Ruby 对象,在本例中是具有 x 和 y 坐标的位置。

标签: ruby rspec


【解决方案1】:

为了测试一个方法是否被调用,你模拟这个方法(创建一个假的方法),它会模仿你正在测试调用的方法。在 Ruby 中,所有函数都是 something 上的方法,即使那是主要对象(在此上下文中为 self)。如果您实际上是在某个类上测试方法(您应该这样做;在 main 上定义方法对 Ruby 代码的可维护性非常不利),请将 self 替换为 Foo.new 或类似名称。

如果你不告诉我们函数应该做什么,然后编写错误,就很难创建一个测试用例,所以我会稍微修复它们,你可以稍后根据你的用例调整它们:

def manipulate_loc(loc, op, n)
    x = loc.x.send(op, n)
    y = loc.y.send(op, n)
    [x, y]
end

def scale_up(loc, n)
    manipulate_loc(loc, :*, n)
end


it 'can scale up Locations' do
  expect(self).to receive(:manipulate_loc).with(subject, :*, 2).and_return([4, 10])
  expect(scale_up(subject, 2)).to equal([4, 10])
end

expect... to receive... with... and_return... 正在制作一个以指定方式运行的假方法,并用它替换您的方法。如果调用了 fake 方法,则测试通过。 (还有一个进一步的期望是,您调用模拟方法的方法实际上是在做正确的事情。)

【讨论】:

  • 感谢@Amadan,当我有更多空闲时间时,我会试一试。正如我在上面的其他评论中所说,目标是轻松地动态改变类属性(使用块和过程)。这是一个 Gosu 项目,我在其中建模随机在屏幕上移动的“错误”(位置)。
  • 我想尽可能地限制传递数组和散列的使用,以期更好地掌握 Ruby 块。
猜你喜欢
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 2013-08-22
  • 2020-12-16
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多