ruby - Spec RSpec 模型属性 setter

标签 ruby attributes rspec setter

我正在使用 Sinatra (1.2) 和 RSpec (2.5),并希望创建一个具有属性 TDD 样式的新对象。最终结果应该是这样的:

class User
  def initialize(name)
    @name = name
  end
end

我知道我必须在实现之前编写示例,但我想在这里解释我的问题。 :) 这是我目前无法使用的规范:

describe User
  it "creates a new user object" do
    name = mock("A name")
    user = mock(User) # shouldn't do this, see the reply's
    user.should_receive(:name=).with(name)
    User.new(name)
  end
end

当我运行 RSpec 时,出现“预期:1 次,收到 0 次”错误。知道如何解释 RSpec 我想分配名称属性吗?

注意:我没有使用 Rails,没有使用 ActiveRecord 或其他任何东西,只使用了 Ruby。

最佳答案

首先,让我解释一下为什么您编写的规范不起作用:

您设置了一个期望,即 mock(User) 返回的模拟对象应该接收 name=。这有两个问题。首先,mock 不会收到任何东西,因为它从未被调用过。 mock(User) 返回一个模拟对象,它不能用于设置对 User 类对象将接收的内容的期望(要做到这一点,只需执行 User.应该接收(...))。其次,即使您对 User 类对象设置了期望,该对象也永远不会收到 name=。这也有两个原因:首先,因为 name=(如果它存在)将是一个实例方法,因此不会在类对象上调用,其次,您声明没有 name= 实例方法。您的代码所做的是设置一个实例变量。

现在,您应该如何为此编写测试?你不应该。测试是为了定义和断言行为,而不是实现。设置实例变量是纯粹的实现。在您的示例代码中无法从类外部获取 @name 实例变量的值,因此没有理由为其编写测试。

显然您的代码只是一个示例,任何有用的东西都会对 @name 变量做一些事情,这就是您应该测试的内容。首先为 User 对象的用途编写测试,然后编写完成该测试所需的所有实现(但仅此而已)。编写反射(reflect)对象将如何在实际生产代码中使用的测试。

关于ruby - Spec RSpec 模型属性 setter ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5603588/

相关文章:

ruby-on-rails - Rspec 和 Draper : unitialized constant on class name

ruby - 安装 yajl-ruby 有一些错误

ruby-on-rails - 在子模型中访问父对象

gwt - smartgwt setAttribute 命令不起作用

delphi - Delphi 新 RTTI 的实际使用 - 属性、值

ruby-on-rails - 具有链式方法的 Rspec 测试 Controller

ruby-on-rails - 使用 rspec 设计和 OmniAuth twitter 集成测试

ruby - 如何使用 bundler 创建相互依赖的 gem,并使用存储库作为源?

ruby - 如果\n 放在新行上,则忽略 SGR 重置代码

ruby-on-rails - rails : difference between attr_accessor and attr_accessible