我的Writer模型类上没有'posting_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类,但奇怪的是我仍然可以访问我的编写器工厂的其他属性。希望这是有道理的,谢谢。
此外,还有其他人在测试中做过类似的事情,这是处理这种情况的最佳方法吗?如果您尝试设置一个不存在的属性,它会创建它,就好像在JavaScript中一样。
答案 0 :(得分: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