Rspec +工厂女孩(没有铁轨!)

时间:2015-02-23 09:08:50

标签: ruby testing rspec selenium-webdriver factory-bot

我正在使用Rspec和selenium-webdriver gem来测试一个Web应用程序。我想在我的测试中排除工厂以模仿用户,而不是每次都手动创建用户。 所以,我做了gem install factory_girl,在我的spec_helper中添加了必需的内容,创建了一个工厂并在我的spec文件中包含了一些行。在运行测试时,我收到错误 失败/错误:FactoryGirl.build(:user)      NameError:        未初始化的常量用户

这是我的spec_helper.rb

RSpec.configure do |config|
  config.include FactoryGirl::Syntax::Methods
  config.expect_with :rspec do |expectations|
  expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end

我的个工厂.rb文件:

 FactoryGirl.define do
  factory :user do
    name "testuser"
    password "freestyle"
    inventory true
  end
end

我的test_spec文件:

require "json"
require "selenium-webdriver"
require "rspec"
require "factory_girl"
FactoryGirl.find_definitions
include RSpec::Expectations

describe "MallSpec" do

  before(:all) do
    FactoryGirl.build(:user)
    @driver = Selenium::WebDriver.for :firefox
    @base_url = "http://localhost:9000/"
    @accept_next_alert = true
    @driver.manage.timeouts.implicit_wait = 30
    @driver.manage.window.resize_to(1301, 744)
    @verification_errors = []
end

我的spec_file位于项目的根目录中。我的factories.rb文件在/ spec dir以及test_spec.rb本身。 任何人都可以帮我解决这个问题或指出我做错了吗?

2 个答案:

答案 0 :(得分:1)

  

运行测试时出现错误失败/错误:   FactoryGirl.build(:user)NameError:uninitialized constant User

您的用户类必须定义。以下是定义no User class的测试:

require 'factory_girl' 

RSpec.configure do |config|
  config.include FactoryGirl::Syntax::Methods
end

FactoryGirl.define do 
  factory :user do 
    name 'Alice'
    age 10
  end
end

describe "MallSpec" do
  let(:test_user) { FactoryGirl.build(:user) }

  describe "user's name" do
    it "equals 'Alice'" do
      expect(test_user.name).to eq('Alice')
    end
  end

end

--output:--
$ rspec 1.rb 
F

Failures:

  1) MallSpec user's name equals 'Alice'
     Failure/Error: let(:user) { FactoryGirl.build(:user) }
     NameError:
       uninitialized constant User
...

添加User class的定义:

require 'factory_girl' 

#====NEW CODE=====
class User
  attr_accessor :name, :age
end
#=================

RSpec.configure do |config|
  config.include FactoryGirl::Syntax::Methods
end

FactoryGirl.define do 
  factory :user do 
    name 'Alice'
    age 10
  end
end

describe "MallSpec" do
  let(:test_user) { FactoryGirl.build(:user) }

  describe "user's name" do
    it "equals 'Alice'" do
      expect(test_user.name).to eq('Alice')
    end
  end

end

--output:--
$ rspec 1.rb 
.

Finished in 0.0024 seconds (files took 0.35197 seconds to load)
1 example, 0 failures

我希望这里的factory()方法:

  factory :user do 
    name 'Alice'
    age 10
  end

......做了类似的事情:

def factory(model_name)
   target_class = constant_get(model_name.capitalize)

...为了构造User类的真实实例。换句话说,factory_girl构造了应用程序中已存在的类的实例 - factory_girl不会模拟类。

答案 1 :(得分:1)

如果您实际上没有User课程但想要使用FactoryGirl生成属性,则可以覆盖该课程:

require "ostruct"

FactoryGirl.define do
  factory :user, class: OpenStruct do
    name "testuser"
    password "freestyle"
    inventory true

    # This isn't necessary, but it will prevent FactoryGirl from trying
    # to call #save on the built instance.
    to_create {}
  end
end

如果您只想要一个attributes_for,则可以使用Hash;如果您想要一个响应create等方法的对象,则可以使用name

如果要生成用于API的JSON,可以使用Hashie::Mash之类的库:

factory :user, class: Hashie::Mash do
  # ...
end

# In your tests:
user_json = create(:user).to_json