【问题标题】:Rspec stub doesn't workRspec存根不起作用
【发布时间】:2012-03-31 17:57:15
【问题描述】:

我有以下规范来测试控制器方法:

context "#create" do
  it "should redirect when model is valid" do
    User.stub!(:valid?).and_return(true)
    post :create, :user => FactoryGirl.attributes_for(:user)
    response.should redirect_to("/")
  end
  it "should render new template when model is invalid" do
    User.stub!(:valid?).and_return(false)
    post :create, :user => FactoryGirl.attributes_for(:user)
    response.should render_template(:new)
  end
end

还有控制器本身:

def create
  @user = User.new(params[:user])
  if @user.save
    redirect_to "/", :notice => "User created"
  else
    render "new"
  end
end

非常简单的代码,但不知何故 stub! 方法并没有真正存根,所以第二个规范失败了 expecting <"new"> but rendering with <"">。它只是像 valid? 返回 true 一样重定向。

我对 Rails 世界很陌生。我错过了什么?谢谢。

【问题讨论】:

    标签: ruby-on-rails ruby rspec


    【解决方案1】:

    当保存一个对象时,Rails 会在一个类的实例上调用valid?。但是您已经在 类本身 上存根 valid?。那是行不通的。

    你想要在这里做的是存根save在正在保存的用户的实例上,例如

    User.stub(:new) { mock_model(User, :save => true) }

    @user = User.new # @user 现在是一个模拟对象

    @user.save#模拟对象返回true

    另一个例子:

    User.stub(:new) { mock_model(User, :save => false) }

    @user = User.new # 再次,@user 是一个模拟

    @user.save#模拟对象返回false

    【讨论】:

    • 天啊谢谢你的提示!这就是问题所在。虽然我认为存根低级方法会更好,比如valid?。这样我就可以将操作从 save 重构为 buildcreate 而不会破坏功能和测试。当然,在这种情况下并非如此。现在我已经通过将存根附加到用户User.any_instance.stub(:valid?).and_return(true) 的所有实例来解决它。但是你对实例和类的提示是我一般错过的。
    • 至于存根valid? 而不是save,我的观点正好相反:) 你关于重构的观点很好,但我们可以扭转这种局面——如果ActiveRecord 被重构,save 不再调用 valid? ?现在,由于您无法控制的库的内部实现,您的测试中断了。
    • 好吧,在我们在开发/测试中测试之前,我们几乎不会在生产中切换 ActiveRecord,不是吗? :) 如果我们将在开发/测试中,那么这将是显而易见的,因为从这一点开始测试将失败。所以我们总是可以联系到变更日志或其他东西来找出原因。从我的角度来看,应用程序类很可能会比核心类进行重构。
    • @zetetic :这是一个相当古老的线程,有一个奇怪的问题,有没有办法重置存根本身?应该有一种方法可以在不同的测试用例中返回不同的值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 2021-02-01
    • 1970-01-01
    相关资源
    最近更新 更多