【问题标题】:Rspec: Creating user before testing methodRspec:在测试方法之前创建用户
【发布时间】:2016-08-25 20:36:08
【问题描述】:

您好,我是 rspec(以及一般的单元测试)的新手,想测试以下方法:

class HelloController < ApplicationController

  def hello_world
    user = User.find(4)
    @subscription = 10.00
    render :text => "Done."
  end
end

我正在尝试像这样使用 Rspec:

Describe HelloController, :type => :controller do

    describe "get hello_world" do

      it "should render the text 'done'" do
        get :hello_world
        expect(response.body).to include_text("Done.")
      end
    end
  end

我想简单地测试该方法是否正常工作并使测试“完成”。运行测试时出现以下错误:

 Failure/Error: user = User.find(4)

 ActiveRecord::RecordNotFound:
   Couldn't find User with 'id'=4

但是在执行之前如何正确创建具有该 ID 的用户?我根据其他教程和问题尝试了以下方法,但它不起作用:

describe "get hello_world" do
        let(:user) {User.create(id: 4)}

            it "should render the text 'done'" do
                get :hello_world
                expect(response.body).to include_text("Done.")
            end
    end

提前谢谢你。

【问题讨论】:

标签: ruby-on-rails unit-testing rspec


【解决方案1】:

嘿,所以真的没有任何动作(例如 def hello_world)应该依赖于特定的 id。因此,一个简单的替代方法是使用user = User.last 或通过名称user = User.find_by(name: "name") 查找用户。然后在测试中,如果您在操作中使用User.last,您将创建任何用户。

describe "get hello_world" do
  let(:user) {User.create!}

  it "should render the text 'done'" do
    get :hello_world
    expect(response.body).to include_text("Done.")
  end
end

或者如果您按名称搜索,您可以使用该名称创建用户;

describe "get hello_world" do
  let(:user) {User.create!(name: "name")}

  it "should render the text 'done'" do
    get :hello_world
    expect(response.body).to include_text("Done.")
  end
end

希望对你有帮助,欢迎提问。

【讨论】:

    【解决方案2】:

    你真的要使用'user = User.find(4)'吗?如果你真的打算这样做,你应该存根用户的 find 方法并返回一个用户对象。

    it "should render the text 'done'" do
      u = User.new #a new user, your test database is empty, so there's no user with id 4
      User.stub(find: u) #stub the User's find method to return that new user
      get :hello_world
      expect(response.body).to include_text("Done.")
    end
    

    另一种选择是通过参数发送 user_id

    it "should render the text 'done'" do
      u = User.create(.... your user params)
      get :hello_world, user_id: u.id
      expect(response.body).to include_text("Done.")
    end
    

    def hello_world
      user = User.find(params[:user_id])
      @subscription = 10.00
      render :text => "Done."
    end
    

    无论如何,我认为您不应该这样做,硬编码的 id 是一个不好的迹象。如果您需要控制用户注册和登录,您可以使用 Devise 之类的东西,并且您可能需要在规范之前创建用户登录。

    【讨论】:

      猜你喜欢
      • 2019-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多