2015-02-23 72 views
3

我使用Rspec和硒-webdriver gem来测试一个web应用程序。我想在我的测试中排除工厂模拟用户,而不是每次手动创建用户。 所以,我做了gem安装factory_girl,在spec_helper中添加了需要的内容,创建了一个工厂并在我的spec文件中包含了一些行。并运行测试时,我得到一个错误 故障/错误:FactoryGirl.build(:用户) NameError: 未初始化的常数用户Rspec +工厂女孩(没有导轨!)

这里是我的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 

我factories.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目录以及test_spec.rb本身。 任何人都可以帮助我解决这个问题或指出我做错了什么?

+0

什么是“用户”在您的应用程序的情况下? – meagar 2015-02-23 19:53:16

回答

1

And when running the test I get an error Failure/Error: 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 :user do 
    name 'Alice' 
    age 10 
    end 

...做这样的事情:

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

...为了构建一个User类的实例。换句话说,factory_girl构造了应用中已经存在的类的实例 - factory_girl不会嘲笑类。

+0

谢谢你的回答,这有助于很多。我以为Factory Girl会自己嘲笑一个用户类。我们的后端是用PHP写的,而不是ruby,前端客户端用JSON接收这些数据。所以,我必须用rspec重新考虑我的测试方法。 – 2015-02-24 12:07:09

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的对象。

您可以使用像Hashie::Mash库如果要生成使用JSON你的API中:

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

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

非常感谢,我现在就试试这个,并在稍后发布结果! – 2015-02-26 12:55:48