我正在构建一个非常小的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
以下是代码覆盖率的输出:
疯狂......我迷路了!编辑:
此外我还有一个if !user
rspec挂钩,但不应该是importat,因为它只在所有测试后运行:
after all
答案 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