Rspec无法识别Sinatra app中的表格

时间:2016-05-05 01:45:56

标签: ruby postgresql activerecord rspec sinatra

我正在创建一个轻量级的应用程序,需要自定义路由,所以我使用Sinatra over Rails。但是,我正在使用一个非常模仿Rails功能的骨架,而不必在任何时候都打算使用常规。

问题在于,当我尝试运行Rspec时,它告诉我没有关系。我一直认为必须有一个多元化的问题,但是对于我来说,我找不到它。我不是想做任何花哨的事情,但只是能够做出一些事情,所以我可以开始进行验证等等。

代码示例:

问题

当我运行bundle exec rspec:

  1) Admin successfully creates Admin
 Failure/Error: admin = Admin.new
 ActiveRecord::StatementInvalid:
   PG::UndefinedTable: ERROR:  relation "admins" does not exist
   LINE 5:                WHERE a.attrelid = '"admins"'::regclass
                                             ^
   :               SELECT a.attname, format_type(a.atttypid, a.atttypmod),
                        pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
                   FROM pg_attribute a LEFT JOIN pg_attrdef d
                     ON a.attrelid = d.adrelid AND a.attnum = d.adnum
                  WHERE a.attrelid = '"admins"'::regclass
                    AND a.attnum > 0 AND NOT a.attisdropped
                  ORDER BY a.attnum
 # ./spec/admin_spec.rb:6:in `block (2 levels) in <top (required)>'

但是在控制台中手动运行:

irb(main):007:0> Admin.all.length
D, [2016-05-04T18:42:02.818958 #30608] DEBUG -- :   Admin Load (1.3ms)  SELECT "admins".* FROM "admins"
=> 0
irb(main):008:0> admin = Admin.new
=> #<Admin id: nil, name: nil, password: nil, created_at: nil, updated_at: nil>
irb(main):009:0> admin.save
D, [2016-05-04T18:42:15.127732 #30608] DEBUG -- :    (0.6ms)  BEGIN
D, [2016-05-04T18:42:15.140416 #30608] DEBUG -- :   SQL (1.1ms)  INSERT INTO "admins" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"  [["created_at", "2016-05-05 01:42:15.130599"], ["updated_at", "2016-05-05 01:42:15.130599"]]
D, [2016-05-04T18:42:15.146401 #30608] DEBUG -- :    (2.3ms)  COMMIT
=> true
irb(main):010:0> Admin.all.length
D, [2016-05-04T18:42:28.236480 #30608] DEBUG -- :   Admin Load (2.1ms)  SELECT "admins".* FROM "admins"
=> 1

代码

模特:

class Admin < ActiveRecord::Base
  # Remember to create a migration!
end

迁移:

class CreateAdmins < ActiveRecord::Migration
  def change
    create_table :admins do |t|
      t.string :name
      t.string :password

      t.timestamps
    end
  end
end

规范:

require 'spec_helper'

describe Admin do

  it "successfully creates Admin" do
    admin = Admin.new
    expect(admin.save).to change{Admin.all.length}.by(1)
  end

end

spec helper:

require 'rubygems'

ENV['RACK_ENV'] ||= 'test'

require File.expand_path("../../config/environment", __FILE__)
require 'shoulda-matchers'
require 'rack/test'
require 'capybara'
require 'capybara/rspec'

RSpec.configure do |config|
  config.include Rack::Test::Methods
end

def app
  Sinatra::Application
end

Capybara.app = app.new

我希望这是足够的信息,这是我的第一个问题,告诉我你是否需要更多,或者更少会更好。谢谢!

此外,我已经看到了涉及Rails特定的rake任务的解决方案。其中大部分都不存在于Sinatra中,我很难找到源代码将其导入我的Sinatra应用程序。

2 个答案:

答案 0 :(得分:0)

那是因为rspec在测试环境中运行。您的应用似乎没有测试数据库。

我在第一次运行代码时遇到了同样的问题

[retgoat@iMac-Roman ~/temp/sinatra-activerecord-starter-kit]$ git:(master) be rspec
.F

Failures:

1) Admin successfully creates Admin
 Failure/Error: admin = Admin.new

 ActiveRecord::StatementInvalid:
   PG::UndefinedTable: ERROR:  relation "admins" does not exist
   LINE 5:                WHERE a.attrelid = '"admins"'::regclass
                                             ^
   :               SELECT a.attname, format_type(a.atttypid, a.atttypmod),
                        pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
                   FROM pg_attribute a LEFT JOIN pg_attrdef d
                     ON a.attrelid = d.adrelid AND a.attnum = d.adnum
                  WHERE a.attrelid = '"admins"'::regclass
                    AND a.attnum > 0 AND NOT a.attisdropped
                  ORDER BY a.attnum

Finished in 0.09315 seconds (files took 1.28 seconds to load)
2 examples, 1 failure

然后我创建了测试数据库

[retgoat@iMac-Roman ~/temp/sinatra-activerecord-starter-kit]$ git:(master) ENV=test rake db:setup
sinatra_development already exists
sinatra_test already exists
-- enable_extension("plpgsql")
   -> 0.0100s
-- create_table("admins", {:force=>:cascade})
   -> 0.0109s
-- initialize_schema_migrations_table()
   -> 0.0016s
-- enable_extension("plpgsql")
   -> 0.0104s
-- create_table("admins", {:force=>:cascade})
   -> 0.0186s
-- initialize_schema_migrations_table()
   -> 0.0046s

稍微改变了你的测试:你应该在expect {}.to change中使用一个块,而不仅仅是prenthesis。 因为它会失败

  1) Admin successfully creates Admin
     Failure/Error: expect(admin.save).to change{Admin.all.length}.by(1)
       expected result to have changed by 1, but was not given a block
     # ./spec/models/admin_spec.rb:5:in `block (2 levels) in <top (required)>'

所以只需用一个块替换括号

describe Admin do

  it "successfully creates Admin" do
    admin = Admin.new
    expect { admin.save }.to change{Admin.all.length}.by(1)
  end

end

并测试wil pass

[retgoat@iMac-Roman ~/temp/sinatra-activerecord-starter-kit]$ git:(master) be rspec
D, [2016-05-05T08:52:22.200133 #16356] DEBUG -- :   Admin Load (0.1ms)  SELECT "admins".* FROM "admins"
.

Finished in 0.03326 seconds (files took 0.77676 seconds to load)
2 examples, 0 failures

答案 1 :(得分:0)

rake db:migrate RACK_ENV = test

我不会撒谎,我试过六次。但它终于有效地为下一个可怜的灵魂走下兔子洞......