Rspec:在测试方法之前创建用户

时间:2016-08-25 20:36:08

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

您好我是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

我想简单地测试一下该方法是否正常工作并进行测试&#34;完成&#34;。运行测试时出现以下错误:

 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

提前谢谢。

2 个答案:

答案 0 :(得分:2)

嘿所以真的没有动作(例如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

希望这有帮助,欢迎提问。

答案 1 :(得分:1)

你真的想要使用&#39; user = User.find(4)&#39;?如果你真的想这样做,你应该存根用户的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

另一种选择是通过params发送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之类的东西,并且您可能需要在规范之前创建用户登录。