Rails rspec 测试中编辑 factorygirl 生成的对象的疑惑

ane · 2014年05月01日 · 最后由 wikimo 回复于 2014年05月01日 · 2123 次阅读

各位大大,测试是选择rails Tutorial.

先上测试代码

describe "edit" do
    let(:user) { FactoryGirl.create(:user) }
    before { visit edit_user_path(user) }
    describe "page" do
      it { should have_content("Update your profile") }
      it { should have_title("Edit user") }
      it { should have_link('change', href: 'http://gravatar.com/emails') }
    end

在上controller

def edit
  @user = User.find(params[:id])
end

测试是通过的。只是我的疑惑是这样的。测试中的let(:user) { FactoryGirl.create(:user) }创建了一个user对象(我是觉得它没有id的)。 这样调用visit edit_user_path(user)的话,显然不可能生成..user/:id/edit这样的url(因为user中我觉得没有id)

但是:事实是测试通过的,所以想必FactoryGirl.create(:user)是生成了id。熟悉FactoryGirl的给解答一下吧,先谢谢了。

PS: 看到FactoryGirl,我就想起早年有个段子。“who create the table girl,and I should wirte the sql like "insert into girl ...."”

共收到 12 条回复

疑问在哪?

tailf log/test.log

或者干脆 let(:user) { u=FactoryGirl.create(:user); puts u.new_record?; u }

用一个库/框架的时候先把文档读完比较好,或者像上面这样动手试。不好用猜的

# Returns a User instance that's not saved
user = build(:user)

# Returns a saved User instance
user = create(:user)

# Returns a hash of attributes that can be used to build a User instance
attrs = attributes_for(:user)

# Returns an object with all defined attributes stubbed out
stub = build_stubbed(:user)

# Passing a block to any of the methods above will yield the return object
create(:user) do |user|
  user.posts.create(attributes_for(:post))
end

我是直接再test代码里puts的,快又准

#3楼 @xds2000 puts带来光明。失去了puts,生活会怎样?

#1楼 @Rei 疑问就是edit_user_path(FactoryGirl.create(:user))这样ok吗?生成的user有id属性吗

#2楼 @yuan 谢谢你的回答,我觉得对我很有帮助,只是我该用了 p u,效果比你的好点。文档是以后要一定读的,

create没问题吧? 打印下就知道了,build就有问题了.

create应该是吧数据插到表里的 你可以create后User.first看看

这个确实是生成了persisted record的。FactoryGirl.create直接呼叫model的create,生成正常的记录。但build_stubbed就不会。在controller测试中用create是正确的。

let是懒方法,不叫不动的。因为你在edit_user_path(user)里面叫了它,所以记录生成了,测试通过。

let有时要注意的。这个测试没有问题,但你如果测试index, 前面用了let(:user){FactoryGirl.create :users, 5)}, 后面就会通不过,因为你不呼叫记录就不能生成。这时就要用let!强制生成。

这里定义了user,FactoryGirl.create(:user) 按照它创建的,它当然是有数据库ID的。

FactoryGirl.define do
  factory :admin, class: User do
    email 'admin@qing.cn'
    password '123456'
    password_confirmation '123456'
  end

  factory :user do
    email 'user@qing.cn'
    password '123456'
    password_confirmation '123456'
    factory :user_with_orders do
      ignore do
        orders_count 5
      end

      after(:create) do |user, evaluator|
        create_list(:order, evaluator.posts_count, user: user)
      end
    end
  end
end

最简单的方法是 p 一下它,比如

describe "with user's address" do
      let(:user_address) { FactoryGirl.create(:address) }
      p user_address

id属性是自动添加的啊,任何框架都这样。你factory.create 和程序里create进行的操作是一样。你程序里create的时候,也会指明id吗?

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册