我刚刚想出如何在型号User上显示国家/地区ID号的国家/地区名称。这是我在控制器中使用的基本代码和两个视图,用于通过其ID找到User后显示名称:
@country_name = Country.find(@user.country_id).name
我正在使用Factory Girl来模拟美国境内country_id的默认值为1的用户记录。在我添加这个逻辑之前,我的Rspec2测试很干净。现在,当我运行测试时,我收到以下错误。在视图或控制器中具有类似逻辑的每个测试都会产生错误。
ActiveRecord::RecordNotFound:
Couldn't find Country with id=1
以下是我正在进行的两项Rspec2测试:
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
before { visit user_path(user) }
it { should have_selector('span', text: user.first_name+' '+user.last_name) }
it { should have_selector('title', text: user.first_name+' '+user.last_name) }
end
个人资料页面引用@country_name,如上所述设置。国家/地区名称会按预期显示在屏幕上。
我认为我需要以某种方式为Rspec2测试添加一些东西。我不知道该怎么做。由于@country_name是一个与User无关的实例变量,我觉得我可能需要在Rspec2文件中直接执行某些操作。
任何帮助将不胜感激。到目前为止我还没有找到这样的东西,但我会继续寻找。
2012年6月8日更新下午7:27 CDT
这是我的用户控制器逻辑。在此处添加第二行会产生RSpec2错误。我在RSpec2测试中没有改变任何东西。 show.html.erb中引用了@country_name。
def show
@user = User.find(params[:id])
@country_name = Country.find(@user.country_id).name
end
我决定尝试这个,但得到了同样的错误:
describe "profile page" do
let(:user) { FactoryGirl.create(:user) }
let(:country) { FactoryGirl.create(:country) }
before { visit user_path(user) }
it { should have_selector('span', text: user.first_name+' '+user.last_name) }
it { should have_selector('title', text: user.first_name+' '+user.last_name) }
end
我将以下内容添加到与用户工厂分开的factories.rb中。
factory :country do
id 1
name "CountryName"
iso "CN"
end
同样,我的国家/地区名称的应用程序逻辑非常有用。
更新6/11/2012上午9:09 CDT
这是我的factories.db文件。 country_id在User中的默认值为1。我尝试使用country_id定义如下,没有country_id的声明。我也有没有身份证的乡村工厂。我仍然有所描述的错误。我在这里提交问题之前尝试了这个。
FactoryGirl.define do
factory :user do
sequence(:first_name) { |n| "First Name #{n}" }
sequence(:last_name) { |n| "Last Name #{n}" }
sequence(:username) { |n| "Username#{n}" }
sequence(:email) { |n| "person_#{n}@example.com" }
password "foobar"
password_confirmation "foobar"
sequence(:city) { |n| "City #{n}" }
sequence(:state_province) { |n| "State/Province #{n}" }
active_user "1"
country_id 1
factory :admin do
admin true
active_user "3"
end
factory :blocked do
active_user "1"
end
factory :rejected do
active_user "2"
end
factory :not_visible do
active_user "3"
visible false
end
factory :visible do
active_user "3"
visible true
end
end
factory :country do
id 1
name "CountryName"
iso "CN"
end
end
更新6/11/2012 5:37 pm CDT
经过几个小时的继续搜索并完全重新启动我的计算机(叹气),我终于能够让测试工作了。我在用户工厂中用user.association:country替换了country。在描述“个人资料页面”之后,我将原来的两个陈述放回去。根据建议的更改,我现在没有错误。我想该关联将在Country中创建相应的行。
非常感谢所有的帮助。这是收到的帮助和解决这个问题的一个修改的组合。
确定如何检查更改的值.......
2012年12月12日上午10:55
看起来所有的代码更正我都可以使用@ user.country.name而没有错误。我将更改我的代码以使用此流线编码。
答案 0 :(得分:2)
让我们更多地设置用于测试的变量,如果你正在使用数据库清理器或类似的东西,这些可能会在每次测试运行时在数据库中被销毁。您应该在之前的区块中设置工厂:
编辑:我刚刚意识到这可能是因为你试图通过明确输入ID来匹配记录。这不起作用(id由数据库自动设置),但是Factory Girl应该处理你的关联,看看你在设置before块时会发生什么:
before(:each) do
country = FactoryGirl.create(:country)
user = FactoryGirl.create(:user, country: country)
visit user_path(user)
end
我也会删除
id 1
来自您所在国家/地区的工厂,以及在用户工厂中将country_id设置为1的行。
编辑2:您需要告诉Factory Girl您的关联,不要尝试通过明确设置id字段来设置它们,因为这不起作用。
删除
country_id 1
来自用户工厂
id 1
来自国家工厂的,并将此行添加到用户工厂:
country
(是的,只有国家自己 - 只要工厂和协会的名称相同,工厂女孩就足够聪明地弄明白发生了什么)
顺便说一下,你可以改变这个:
@country_name = Country.find(@user.country_id).name
到
@country_name = @user.country.name
这不会有帮助,但它更清洁。