RSpec失败了。为什么?

时间:2014-02-09 01:37:33

标签: rspec sinatra

我正在构建一个非常小的Sinatra API,今天我开始为它编写测试。我正在使用RSpec和FactoryGirl。

我有一个用户模型,在控制器中,我检查正在注册的用户的电子邮件是否已保存。如果保存,我返回402如果不是我创建用户并返回200.为了测试这个,我正在使用相同的参数两次对users路由进行POST,在我检查的第一个{ {1}}因为数据库是空的所以我可以创建用户,然后我有另一个测试,POST到last_response.should be_ok路由的路径与之前相同,但期望users和我'得到200!所以测试失败!!

这是我的Sinatra路线:

last_response.should_not be_ok

这是我的考验:

post '/users' do
    user = User.where(email: params[:email]).first

    if !user
        user = User.create(email: params[:username], password_not_hashed: params[:password])
        halt 200, {user:user}.to_json
    end 

    halt 409, {error:"user already exists"}.to_json
end

我收到失败,因为上次测试的回复是200.我已经打印了describe 'Create User' do include Rack::Test::Methods params = {} params['password'] = "username" params['username'] = "username@username.com" it "should create a user" do post '/users', params last_response.should be_ok end it "should fail to create a user because its duplicate user" do post '/users', params last_response.should_not be_ok end end params last_response,这就是我得到的:

PARAMS:

pp

last_response

{"password"=>"username", "username"=>"username@username.com"}

有什么想法吗?!?!这让我发疯了!

编辑:

刚刚添加了有效的记录验证(@block=nil, @body=["{\"user\":{\"id\":null,\"email\":\"username@username.com\"}}"], @body_string=nil, @chunked=false, @errors="", @header= {"Content-Type"=>"text/html;charset=utf-8", "Content-Length"=>"52", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff", "X-Frame-Options"=>"SAMEORIGIN"}, @length=52, @original_headers= {"Content-Type"=>"text/html;charset=utf-8", "Content-Length"=>"52", "X-XSS-Protection"=>"1; mode=block", "X-Content-Type-Options"=>"nosniff", "X-Frame-Options"=>"SAMEORIGIN"}, @status=200, ),在我的测试结果中,我得到以下内容:

validates_uniqueness_of :email

因此,这意味着已经创建了一个包含该电子邮件的用户,所以我仍然不明白为什么测试失败,创建用户的路径总是进入Failure/Error: post '/users', params ActiveRecord::RecordInvalid: Validation failed: Email has already been taken

以下是代码覆盖率的输出: enter image description here

疯狂......我迷路了!

编辑:

此外我还有一个if !user rspec挂钩,但不应该是importat,因为它只在所有测试后运行:

after all

1 个答案:

答案 0 :(得分:2)

感谢您提出详细的问题 - 这非常合理。我怀疑你先前发给/ user的帖子没有在测试之间保留测试数据库中的新用户。您是否尝试在第二次发布呼叫时输入print语句以确保您的测试数据库包含用户?这看起来像这样:

it "should fail to create a user because its duplicate user" do 
    puts User.where(email: params[:email]).first
    post '/users', params
    last_response.should_not be_ok
end

您可能还想安装pry并在测试中添加断点。你可以在这里阅读更多关于撬的内容:https://github.com/pry/pry。这将允许您在代码执行时检查测试数据库的状态。安装pry后,您可以在代码中添加交互式中断,如下所示:

require 'pry'

<other test business happens>


it "should fail to create a user because its duplicate user" do 
    binding.pry
    post '/users', params
    last_response.should_not be_ok
end

如果您的测试数据库确实没有在/ user之间保留帖子之间的数据,那么您可能会尝试使用这样的内容进行第二次测试,以便在尝试发布之前添加用户:

it "should fail to create a user because its duplicate user" do 
    User.create(email: params[:username], password_not_hashed: params[:password])
    post '/users', params
    last_response.should_not be_ok
end