惩戒ActiveRecord的关系beheavior在RSpec的测试

惩戒ActiveRecord的关系beheavior在RSpec的测试

问题描述:

我碰到的这个问题,测试。让我们假设我有两个型号,用户和帖子,其中用户的has_many:帖子

I've run into this problem with testing. Let's assume I have two models, User and Post, where user has_many :posts.

我想SPEC指出,包括像这样一个code座:

I'm trying to spec out a code block that includes something like this:

user = User.find(123)
post = user.posts.find(456)

我知道如何模拟出的 User.find user.posts 部分。该 user.posts 模拟返回后对象的数组。当它获得的,以 .find(456)部分,一切都打破了以没有给出异常块。

I know how to mock out the User.find and user.posts parts. The user.posts mock returns an array of Post objects. And when it get's to .find(456) part, everything breaks down with no block given exception.

所以,在这里我的问题是:我该怎么回报为 user.posts 模拟的结果,使 .find(456)方法的工作就可以了? User.first.posts.class 说,这是阵列,但显然有更多的东西,使AR式呼叫找到工作。我不是嘲笑了find方法返回的对象上的前景喜出望外。

So my question here is: what do I return as the result of the user.posts mock, so that .find(456) method works on it? User.first.posts.class says it's Array, but obviously there's something more that makes the AR-style find calls work. I'm not overjoyed by the prospect of mocking out find method on the returned object.

PS之前建议停止嘲笑约和使用夹具/提供必要的数据无欲无求的测试数据库的明显,很好的答案,这里的渔获:传统的方案。用户和帖子上的数据库视图没有表上工作,并改变它,以便他们在测试数据库中的表似乎是错误的我。

PS Before you suggest the obvious and good answer of stop mocking about and using fixtures/seeding the test database with necessary data, here's the catch: legacy scheme. Both User and Post work on top of database views not tables, and changing it so that they are tables in test database seems wrong to me.

问题是, user.posts 不是的实际上的简单阵列;它的关联代理对象。存根的方式很可能是这样的(虽然确切的语法取决于它嘲弄框架您正在使用):

The issue is that user.posts isn't actually a simple Array; it's an association proxy object. The way to stub it is probably something like this (though the exact syntax depends on which mocking framework you're using):

def setup
  @user = mock(User)
  User.stub(:find).with(123).return(@user)
  user_posts = mock(Object)
  @user.stub(:posts).return(user_posts)
  @post = mock(Post)
  user_posts.stub(:find).with(456).return(@post)
end

然后在您的测试, User.find(123)返回 @user @ user.posts.find(456)返回 @post 。如果您需要 @ user.posts 来像更多的阵列在你的测试,你可以创建一个模拟(阵列)和存根的 [](指数)方法。

Then in your test, User.find(123) will return @user and @user.posts.find(456) will return @post. If you need @user.posts to act like more of the Array in your tests you can create a mock(Array) and stub the [](index) method.