3

我想问题是我不知道如何正确使用带有 Rspec 的工厂女孩​​。或者就此正确地在rails中进行测试。不过还是觉得有点怪。。

我有一个类,用户,具有以下工厂:

FactoryGirl.define do
  factory :user do
    name     "admin"
    email    "admin@admin.com"
    adminstatus  "1"
    password "foobar"
    password_confirmation "foobar"
  end

  factory :user_no_admin, class: User do
    name     "user"
    email    "user@user.com"
    adminstatus  "2"
    password "foobar"
    password_confirmation "foobar"
  end
...

我的测试如下所示:

...
describe "signin as admin user" do
  before { visit login_path }
  describe "with valid information" do
    let(:user_no_admin) { FactoryGirl.create(:user_no_admin) }
    let(:user) { FactoryGirl.create(:user) }
    before do
      fill_in "User",    with: user.name
      fill_in "Password", with: user.password
      click_button "Login"
    end

    it "should list users if user is admin" do 
      response.should have_selector('th', content: 'Name') 
      response.should have_selector('td', content: user_no_admin.name)
      response.should have_selector('td', content: user.name)
    end
  end      
end#signin as admin user
...

基本上我正在尝试测试,如果您以管理员身份登录,您应该会看到所有用户的列表。我稍后会在文件中测试以非管理员身份登录。我已经在数据库中有几个用户。

在登录的用户“管理员”列表中,与数据库中已有的用户一起显示。但是,除非我以前做过这样的事情,否则不会显示“用户”:

fill_in "User",    with: user_no_admin.name
fill_in "Password", with: user_no_admin.password

好像除非我使用它,否则它就不会存在。但是,如果我使用 puts 它会打印我输入的信息,即使我没有执行上面的“fill_in”。

我有一个类似的例子,其中 puts 可以帮助我。

describe "should have company name" do
  let(:company) { FactoryGirl.create(:company) }
  let(:category) { FactoryGirl.create(:category) }
  let(:company_category) { FactoryGirl.create(:company_category, company_id: company.id, category_id: category.id) }
  it "should contain companies name" do
    puts company_category.category_id
    get 'categories/' + company.categories[0].id.to_s
    response.should have_selector('h4', :content => company.name)
  end
end

没有上面的puts,我得到一个

Called id for nil

我必须先启动(?)一个由工厂女孩创建的对象,然后才能以某种方式使用它吗?

还需要其他代码吗?

4

4 回答 4

8
let(:whatever) 

直到您第一次调用它们时才创建对象。如果您希望它在首次使用前可用,请使用

let!(:whatever)

反而。

或使用前块:

before(:each) do
  @company = FactoryGirl.create(:company)
  ....
end

这将在您需要使用它们之前创建对象。

于 2012-06-26T11:15:13.683 回答
1

代替:

factory :user do
  name     "admin"
  email    "admin@admin.com"
  ...

我会做:

factory :user do |f|
  f.name "admin"
  f.email "admin@admin.com"
  ...

代替:

let(:user_no_admin) { FactoryGirl.create(:user_no_admin) }
let(:user) { FactoryGirl.create(:user) }

我会做:

@user_no_admin = Factory(:user_no_admin)
@user = Factory(:user)
于 2012-06-26T11:08:14.317 回答
1

我打破的现有测试也遇到了类似的问题,原因略有不同,这很有趣。

在这种情况下,被测控制器最初是 call save,但我将其更改为 call save!,并相应地更新了测试。

修改后的测试是:

  • 将实例声明为let语句
  • 设定对保存的期望!方法(例如expect_any_instance_of(MyObject).to receive(:save!)
  • 预期后第一次使用实例。

在内部,看起来 FactoryGirl 正在调用该save!方法,并且在将期望从 save 更改为 save! 之后,实际上没有完成任何工作(并且被测代码无法从数据库中找到实例)我需要更新和没有黑客很难真正通过)

于 2016-04-30T22:24:15.310 回答
-1

尝试在工厂女孩中使用特质,此链接中提到了一个示例

于 2016-05-02T10:37:02.790 回答