惩戒ActiveRecord的关系beheavior在RSpec的测试 [英] Mocking ActiveRecord relationship beheavior in RSpec tests

查看:142
本文介绍了惩戒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.

这篇关于惩戒ActiveRecord的关系beheavior在RSpec的测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆