2016-07-17 61 views
1

我想测试一个JSON API端点,并且由于user.find的调用失败,我得到一个ActiveRecord::RecordNotFound异常。如何使用RSpec模拟数据库调用

我该如何模拟我的测试的活动记录调用,以便返回一些内容并且不会引发异常?

(我用factory_girl此外,如果我可以使用)

def do_something 
    success = false 
    message = "" 

    user = User.find(params[:user_id]) 

    if user.present? 
    # ... 

    if user.save! 
     success = true 
    end 
    end 

    render json: { 
    "success": success, 
    "message": message 
    } 
end 

我的RSpec的样子:

#RSpec.describe Api::UsersController, type: :controller do 

it "should return some JSON" do 
    payload = { 
    user_id: "1", 
    # ... 
    }.to_json 

    post :do_something, payload, format: :json 

    expected = { 
    success: false, 
    message: "" 
    }.to_json 

    expect(response.body).to eq(expected) 
end 

回答

0

那么如果你想嘲笑数据库ActiveRecord的,你可以尝试这样的事情。

let(:user) { build_mock_class.new() } 
before(:all) { create_table } 
after(:all) { drop_table } 

    def build_mock_class 
    Class.new(ActiveRecord::Base) do 
     self.table_name = 'mock_table' 
    end 
    end 

    def create_table 
    ActiveRecord::Base.connection.create_table :mock_table do |t| 
     t.integer :user_id 
     t.timestamps 
    end 
    end 

    def drop_table 
    ActiveRecord::Base.connection.drop_table :mock_table 
    end 

但是你必须在继续之前建立的连接,你可以把你的连接适配器spec_helper

ActiveRecord::Base.establish_connection(
    adapter: 'sqlite3', 
    database: ':memory:' 
) 

你可以用任何你想要的列名,也这将创建表时规范运行并在规范通过后破坏。

注:不要忘记需要你的spec_helperactive_recordsqlite3或任何你想要使用。

希望它有帮助。

+0

你是什么意思,我不实际使用AR? – Blankman

+0

哦,对不起,我忘了你正在写轨道应用程序的规格。其实我需要在开发一个'ruby gem'的同时嘲笑db。对不起,我会更新我的答案。 – Sinscary

1

我认为你需要使用FactoryGirl先创建一个用户,那么您可以在有效载荷传递用户的ID,像这样:

let(:user) { create :user } # create user by FactoryGirl 

it "should return some JSON" do 
    payload = { 
    user_id: user.id, 
    # ... 
    }.to_json 
    ... 
end