在命名空间模型上将factory_girl_rails与Rspec结合使用

发布于 2024-11-15 13:48:46 字数 987 浏览 2 评论 0原文

我有一个网络服务,可以向多个不同的客户提供广告。广告的结构因客户端而异,因此,我通过客户端名称使用模型和控制器的命名空间来区分广告。从高层来看,它看起来像这样:

'app/models/client1/ad.rb'

class Client1::Ad < ActiveRecord::Base
  attr_accessible :title, :description
end

'app/models/client2/ad.rb'

class Client2::Ad < ActiveRecord::Base
  attr_accessible :title, :description, :source
end

实际上,这些模型更复杂并且具有关联,但这不是重点。
我正在使用 rspec-rails 2.4.0 和factory_girl_rails 1.0.1 编写一些单元测试,并且我的所有工厂都运行良好。但是,我无法为命名空间模型定义工厂。我尝试过类似的方法:

Factory.define :client1_ad, :class => Client1::Ad do |ad|
  ad.title       "software tester"  
  ad.description "Immediate opening"
end  

Factory.define :client2_ad, :class => Client2::Ad do |ad|
  ad.title       "software tester"  
  ad.description "Immediate opening"
  ad.source      "feed"
end

它没有完成任务。我环顾四周,但我看到的每个示例都使用非命名空间模型。有人有什么想法吗?任何意见都将受到高度赞赏。

I have a web service that serves Ads to several different clients. The structure of the Ad varies between clients, and therefore, I am using namespaces for my models and controllers by the client name to differentiate between Ads. From the high level, it looks like this:

'app/models/client1/ad.rb'

class Client1::Ad < ActiveRecord::Base
  attr_accessible :title, :description
end

'app/models/client2/ad.rb'

class Client2::Ad < ActiveRecord::Base
  attr_accessible :title, :description, :source
end

In reality, these models are more complex and have associations, but that is not the point.
I am writing some unit tests using rspec-rails 2.4.0 and factory_girl_rails 1.0.1, and all of my factories work great. However, I am not able to define factories for the namespaced models. I've tried something like:

Factory.define :client1_ad, :class => Client1::Ad do |ad|
  ad.title       "software tester"  
  ad.description "Immediate opening"
end  

and

Factory.define :client2_ad, :class => Client2::Ad do |ad|
  ad.title       "software tester"  
  ad.description "Immediate opening"
  ad.source      "feed"
end

It didn't do the job. I looked around, but every single example that I saw was using non-namespaced models. Anyone have any ideas? Any input is greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

素罗衫 2024-11-22 13:48:46

我这里有一个最小的工作示例,也许您可​​以用它来查明您的问题所在。您对 dmarkow 的答案留下的评论向我表明您在其他地方有错误。

app/models/bar/foo.rb

class Bar::Foo < ActiveRecord::Base
end

*db/migrate/20110614204536_foo.rb*

class Foo < ActiveRecord::Migration
  def self.up
    create_table :foos do |t|
      t.string :name
    end
  end

  def self.down
    drop_table :foos
  end
end

spec/factories.rb

Factory.define :foo, :class => Bar::Foo do |f|
  f.name 'Foooo'
end

*spec/models/foo_spec.rb*

require 'spec_helper'

describe Bar::Foo do

  it 'does foo' do
    foo = Factory(:foo)
    foo.name.should == 'Foooo'
  end
end

运行测试:

$ rake db:migrate
$ rake db:test:prepare
$ rspec  spec/models/foo_spec.rb 
.

Finished in 0.00977 seconds
1 example, 0 failures

希望有帮助。

I have a minimal working example here, maybe you could use it to pinpoint where your problem is. The comment you left on dmarkow's answer suggests to me that you have an error someplace else.

app/models/bar/foo.rb

class Bar::Foo < ActiveRecord::Base
end

*db/migrate/20110614204536_foo.rb*

class Foo < ActiveRecord::Migration
  def self.up
    create_table :foos do |t|
      t.string :name
    end
  end

  def self.down
    drop_table :foos
  end
end

spec/factories.rb

Factory.define :foo, :class => Bar::Foo do |f|
  f.name 'Foooo'
end

*spec/models/foo_spec.rb*

require 'spec_helper'

describe Bar::Foo do

  it 'does foo' do
    foo = Factory(:foo)
    foo.name.should == 'Foooo'
  end
end

Running the test:

$ rake db:migrate
$ rake db:test:prepare
$ rspec  spec/models/foo_spec.rb 
.

Finished in 0.00977 seconds
1 example, 0 failures

Hope it helps.

反话 2024-11-22 13:48:46

我想自从这个答案发布后,FactoryGirl 可能会发生变化。我这样做是为了让它发挥作用

Factory.define do
  factory :foo, :class => Bar::Foo do |f|
    f.name 'Foooo'
  end
end

I think maybe FactoryGirl changes since this answer was posted. I did to make it work

Factory.define do
  factory :foo, :class => Bar::Foo do |f|
    f.name 'Foooo'
  end
end
苏辞 2024-11-22 13:48:46

对于当前最新版本的 FactoryGirl (4.5.0),语法如下:

FactoryGirl.define do
  factory :client1_ad, class: Client1::Ad do |f|
    f.title       "software tester"
    f.description "Immediate opening"
  end
end

请注意,client1_ad 可以是您想要的任何名称,因为我们已经强制识别其类名

With the current latest version of FactoryGirl (4.5.0), this is the syntax:

FactoryGirl.define do
  factory :client1_ad, class: Client1::Ad do |f|
    f.title       "software tester"
    f.description "Immediate opening"
  end
end

Notice that client1_ad can be whatever name you want coz we already force identifying its class name.

过去的过去 2024-11-22 13:48:46

我发现这个问题正在调查与 FactoryGirl 相关的问题,在阅读了一些源代码后,我发现我可以通过重命名我的工厂来解决我的问题。

当我在模块内有命名空间的模型类时,例如: Admin::User 我应该像这样定义我的工厂:

factory :'admin/user', class: Admin::User do
  #...
end

而不是:

factory :admin_user, class: Admin::User do
  #...
end

也许这一点信息有一天可能会对某人有所帮助。我的问题的具体情况是,我试图使用 build(scribed_class) 从我的 RSpec 规范中的工厂构建实例,这对于未命名空间的类来说效果很好,但是不适用于模块内的类。原因是,在内部查找工厂时,FactoryGirl 会使用 ActiveSupport 的下划线助手来规范工厂名称。

I found this question looking into a related issue with FactoryGirl and after a little reading of the source I figured out I could solve my problem by renaming my factories.

When I had model classes that were namespaced inside modules, eg: Admin::User I should have been defining my factories like this:

factory :'admin/user', class: Admin::User do
  #...
end

Rather than:

factory :admin_user, class: Admin::User do
  #...
end

Maybe this little tidbit of info might help someone someday. The specifics of my issue was that I was trying to use build(described_class) to build instances from factories in my RSpec specs and this works just fine with un-namespaced classes but not with classes inside modules. The reason is that internally when looking up factories FactoryGirl will use ActiveSupport's underscore helper to normalise the factory name.

扎心 2024-11-22 13:48:46

您是否尝试过传递实际的类,而不是带有类名的字符串:

Factory.define :client1_ad, :class => Client1::Ad do |ad|

Have you tried passing the actual class, rather than a string with the class name:

Factory.define :client1_ad, :class => Client1::Ad do |ad|
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文