2

我的 Writer 模型类上没有“posted_posts”或“rejected_posts”属性。但是,使用此 SQL:

posts = self.posts.select("sum(case when state = 'posted' then 1 else 0 end) as posted_posts, sum(case when state = 'rejected' then 1 else 0 end) as rejected_posts")

我可以访问 Writer 实例上的那些“属性”。但是,当我使用 RSpec 时,我不想进行此查询,但是我无法设置 Writer 实例的这些属性,因为它认为我正在调用一个方法:

writer.rejected_posts = 8 

上面的行导致“未定义的方法'rejected_posts'”

为了“模拟”这些属性,我这样做了:

describe "performance_score" do
    it "should return a score based on the posted_posts and rejected_posts algorithm" do
      class Writer
        attr_accessor :posted_posts, :rejected_posts
      end
      writer = Factory(:writer)
      writer.rejected_posts = 8
      writer.posted_posts = 2
      writer.performance_score.should == 80
    end
  end

我的主要问题是如何将这些方法添加到类中。创建一个新的 Writer 类如何知道与我的 writer 工厂“同步”?我以为我正在为这个测试创建一个新的 Writer 类,但奇怪的是我仍然可以访问我的 writer 工厂的其他属性。希望这是有道理的,谢谢。

另外,有没有其他人在测试中做过类似的事情,这是处理这种情况的最佳方法吗?如果您尝试设置一个不存在的属性,它会像在 JavaScript 中那样创建它,那就太好了。

4

1 回答 1

2

从您的选择查询返回的东西可能不是真正的Writer模型。它可能是一个ActiveRecord::Relation. 为了提供您在 SQL 语句中分配值的方法,它可能正在实现method_missing并检查 AREL 的某种内部哈希设置。

对于模拟测试,你所做的肯定会奏效。另一种选择是使用stub.

it "should return a score based on the posted_posts and rejected_posts algorithm" do
  writer = Factory(:writer)
  writer.stub(:rejected_posts => 8)
  writer.stub(:posted_posts => 2)
  writer.performance_score.should == 80
end
于 2012-11-28T21:52:42.963 回答