0

几个月来,我一直在使用 Rails 3.2 中的测试工作流程,这是我从 Rem Zolotykh 的截屏视频中获得的。它对于验证 Rails 堆栈的基本组件既简单又有用。但是,我是第一次在 Rails 4.0.0 中使用它,我遇到了一个我以前没有遇到过的订单依赖错误。这是用户控制器规范:

需要'spec_helper'

describe UsersController do 
  describe 'POST create' do
    let!(:user) { stub_model(User) }
    it 'sends new message to User class' do # this is the one that fails intermittently
      params = {                            # call this spec 1
        'first_name' => 'Test',
        'last_name' => 'Tester',
        'email_address' => 'test@test.com',
        'password' => 'secret',
        'password_confirmation' => 'secret'
      }
      User.stub(:new).and_return(user)
      User.should_receive(:new).with(params)
      post :create, user: params
    end
    it 'sends save message to user model' do # this one always passes
      User.stub(:new).and_return(user)       # call this spec 2
      user.should_receive(:save)
      post :create
    end
  end
end

这是用户控制器:

class UsersController < ApplicationController
  def new
    @user = User.new
  end

  def create
    user = User.new(params[:user])
    user.save
    render nothing: true
  end
end

应该很简单。但是,当随机测试顺序首先触发 Spec 2 时,spec 1 就会通过。如果首先触发规范 1,它会失败,但规范 2 仍然通过。规格 1 的失败错误:

1) UsersController POST create sends new message to User class
 Failure/Error: post :create, user: params
 NoMethodError:
   undefined method `save' for #<User:0x007f9d1b6baf98>
 # ./app/controllers/users_controller.rb:8:in `create'
 # ./spec/controllers/users_controller_spec.rb:32:in `block (3 levels) in <top (required)>'

我正在使用 rspec-core 2.13.1 和 rspec-rails 2.13.2。我从高处和低处找遍了,一无所获。有任何想法吗?

4

1 回答 1

0

是的,我想是这样。

在案例 1 中,User.new已被存根以返回记忆化的 stub_model。但是,存根模型没有save方法,因此当您执行 时会出现错误,然后依次post :create调用new并调用save结果。

如果您执行第二个规范 1st,它会创建一个预期stub_modelsave被调用,因此案例 1 通过。

我感到困惑的是,let不应该在示例中缓存结果,如https://www.relishapp.com/rspec/rspec-core/v/2-6/docs/helper-methods/let-and中所述-let,所以我认为即使先执行案例 2,案例 1 仍然应该失败。

至于为什么这在 3.2 和 4.0 之间会有所不同,我不知道。祝你好运。

于 2013-06-29T19:27:48.997 回答