3
我点击显示并销毁应该在雇员表的第一个表行中的水豚的链接。根据updated_at时间戳,表应该进行排序,以便最近修改的员工位于最前面。这个调用是否在我的RSpec请求规范中有效?
之前的示例必须创建一个有效的员工通过身份验证。然后在示例开始时,必须创建一名员工进行测试。 这个是应该始终位于表顶部的员工,因为它应该是最近被修改过的。有时它是,有时不是。添加一个睡眠电话修复了这个问题,我想知道这是否有效,或者如果我弄错了。我认为在测试中加入睡眠呼叫是一件坏事。我还想过,如果认证员工是在示例之前创建的,那么即使我的规范运行速度非常快,它仍然应该有一个更早的updated_at时间戳。
认证宏:
module AuthenticationMacros
def login_confirmed_employee
# create a valid employee for access
Factory :devise_confirmed_employee,
:username => 'confirmed.employee',
:password => 'password',
:password_confirmation =>'password'
# sign in with valid credentials
visit '/employees/sign_in'
fill_in 'Username', :with => 'confirmed.employee'
fill_in 'Password', :with => 'password'
click_on 'Sign In'
end
end
有问题的请求规格:
require 'spec_helper'
include AuthenticationMacros
describe "Employees" do
before do
login_confirmed_employee
end
# shows employees
it "shows employees" do
sleep 1.seconds
Factory :employee_with_all_attributes,
:username => 'valid.employee',
:email => '[email protected]',
visit '/employees'
within 'tbody tr:first-child td:last-child' do; click_on 'Show', end
page.should have_content 'valid.employee'
page.should have_content '[email protected]'
end
# destroys employees
it "destroys employees" do
sleep 1.seconds
Factory(:employee)
visit '/employees'
within 'tbody tr:first-child td:last-child' do; click_on 'Delete', end
page.should have_content 'Employee was successfully deleted.'
end
end
而对这里良好的措施是我spec_helper:
require 'spork'
Spork.prefork do
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
ActiveSupport::Dependencies.clear
require 'email_spec'
RSpec.configure do |config|
config.include EmailSpec::Helpers
config.include EmailSpec::Matchers
end
end
Spork.each_run do
require 'rspec/rails'
require 'factory_girl_rails'
require 'capybara/rspec'
require 'capybara/rails'
require 'shoulda'
RSpec.configure do |config|
config.mock_with :rspec
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
end
有时候,我结束了在节目页面或摧毁需要身份验证的员工而不是示例员工。它永远不会发生但如果我添加1秒睡眠呼叫。
因为我已经消除了这是摆在首位造成这一问题的复杂性。然而,对于未来的用户,我觉得在接受这个答案之前我应该详细说明这个问题,因为它很简单:如果竞争条件最终导致数据库的时间戳出现问题,那么在创建一条记录之前使用时间模拟来“旅行”防止竞赛状况 – Blastula