如何编写不考虑批量分配的 rspec 控制器规范 model_mock

发布于 2024-10-28 02:09:21 字数 1497 浏览 0 评论 0原文

我正在使用 rspec 来测试使用声明了 attr_accessible 的模型的控制器。我不想测试 attr_accessible 是否正常工作(我的模型规范就是这样做的),但我确实想确保我的控制器没有进行批量分配。

具体来说,我有一个像这样的模型:

class Post < ActiveRecord::Base
  attr_accessible :body
  validates :body,    :presence => true,
  validates :user,    :presence => true
  belongs_to :user
end

和一个稍微调整过的生成控制器(删除了 xml 格式行):

  def create
    # this line keeps the rspec test mock happy
    @post = Post.new(params[:post].merge(:user => current_user))

    # Below are the correct lines of code for runtime for attr_accessible
    # @post = Post.new(params[:post])
    # @post.user = current_user            

    respond_to do |format|
      if @post.save
        format.html { redirect_to(@post, :notice => 'Post was successfully created.') }
      else
        format.html { render :action => "new" }
      end
    end
  end

我有一个带有模拟控制器的 rspec 测试,该测试通过了上述内容:

describe "POST create" do
  describe "with valid params" do
    it "assigns a newly created post as @post" do
      Post.stub(:new).
        with({'body' => 'hi there', 'user' => @user}) { mock_post(:save => true) }
      post :create, :post => {'body' => 'hi there'}
      assigns(:post).should be(mock_post)
    end
  end
end

我想做的是更改 rspec 测试,以便当我注释掉第一个 @post 行并取消注释以下两个 @post 行时,正确验证控制器。这样,我将验证控制器是否可以与真实模型一起正常工作,但我可以继续使用模拟进行测试。我已经尝试了几种方法,但似乎一直在兜圈子(是的,我是 Rails 和 Rspect 的新手:p)

提前非常感谢!

I'm using rspec to test a controller that uses a model that has attr_accessible declared. I don't want to be testing that attr_accesible is working (my model spec does that), but I do want to make sure my controller isn't doing a mass assignment.

Specifically, I have a model like so:

class Post < ActiveRecord::Base
  attr_accessible :body
  validates :body,    :presence => true,
  validates :user,    :presence => true
  belongs_to :user
end

and a slightly tweaked generated controller (xml format lines removed):

  def create
    # this line keeps the rspec test mock happy
    @post = Post.new(params[:post].merge(:user => current_user))

    # Below are the correct lines of code for runtime for attr_accessible
    # @post = Post.new(params[:post])
    # @post.user = current_user            

    respond_to do |format|
      if @post.save
        format.html { redirect_to(@post, :notice => 'Post was successfully created.') }
      else
        format.html { render :action => "new" }
      end
    end
  end

I have a rspec test with a mock controller that passes with the above:

describe "POST create" do
  describe "with valid params" do
    it "assigns a newly created post as @post" do
      Post.stub(:new).
        with({'body' => 'hi there', 'user' => @user}) { mock_post(:save => true) }
      post :create, :post => {'body' => 'hi there'}
      assigns(:post).should be(mock_post)
    end
  end
end

What I want to do is change the rspec test so that will correctly validate the controller when I comment out the first @post line and uncomment the following two @post lines. That way, I'll be validating that the controller will work work correctly with the real model, but I can continue to use mocks for testing. I've tried several approaches and seem to be going around in circles (and yes, I'm a newbie to Rails and Rspect :p)

Many thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ゝ偶尔ゞ 2024-11-04 02:09:21

检查批量分配。你需要复制它。因此,在请求中发送错误的用户 ID

post :create, :post => {'body' => 'hi there', 'user_id' => '2'}

,然后确保您创建的帖子具有控制器分配的 user_id(假设本例中其 id 不是 2)

assigns(:post)user_id.should be(current_user.id)

To check against mass assignment. you need to replicate it. so send bad user id in the request

post :create, :post => {'body' => 'hi there', 'user_id' => '2'}

then make sure your created post has the user_id assigned by the controller (assuming its id is not 2 in this example)

assigns(:post)user_id.should be(current_user.id)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文