如何重置factory_girl序列?
假设我有一个项目工厂
Factory.define :project do |p|
p.sequence(:title) { |n| "project #{n} title" }
p.sequence(:subtitle) { |n| "project #{n} subtitle" }
p.sequence(:image) { |n| "../images/content/projects/#{n}.jpg" }
p.sequence(:date) { |n| n.weeks.ago.to_date }
end
并且我正在创建项目实例
Factory.build :project
Factory.build :project
此时,下次执行 Factory.build(:project) 时,我将收到一个标题设置为“项目 3 标题”的项目实例等等。并不奇怪。
现在说我希望在这个范围内重置我的计数器。比如:
Factory.build :project #=> Project 3
Factory.reset :project #=> project factory counter gets reseted
Factory.build :project #=> A new instance of project 1
实现这一目标的最佳方法是什么?
我目前使用以下版本:
factory_girl (1.3.1) 工厂女孩轨道 (1.0)
Provided that I have a project factory
Factory.define :project do |p|
p.sequence(:title) { |n| "project #{n} title" }
p.sequence(:subtitle) { |n| "project #{n} subtitle" }
p.sequence(:image) { |n| "../images/content/projects/#{n}.jpg" }
p.sequence(:date) { |n| n.weeks.ago.to_date }
end
And that I'm creating instances of project
Factory.build :project
Factory.build :project
By this time, the next time I execute Factory.build(:project) I'll receive an instance of Project with a title set to "project 3 title" and so on. Not surprising.
Now say that I wish to reset my counter within this scope. Something like:
Factory.build :project #=> Project 3
Factory.reset :project #=> project factory counter gets reseted
Factory.build :project #=> A new instance of project 1
What would be the best way to achieve this?
I'm currently using the following versions:
factory_girl (1.3.1)
factory_girl_rails (1.0)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
只需在您的 before/after 回调中调用 FactoryGirl.reload 即可。这在 FactoryGirl 代码库中定义为:
由于某种原因,调用 FactoryGirl.sequences.clear 是不够的。进行完全重新加载可能会产生一些开销,但是当我尝试使用/不使用回调时,我的测试需要大约 30 秒才能运行。因此,开销不足以影响我的工作流程。
Just call FactoryGirl.reload in your before/after callback. This is defined in the FactoryGirl codebase as:
Calling FactoryGirl.sequences.clear is not sufficient for some reason. Doing a full reload might have some overhead, but when I tried with/without the callback, my tests took around 30 seconds to run either way. Therefore the overhead is not enough to impact my workflow.
有一个名为
sequence_by_name
的类方法可以按名称获取序列,然后您可以调用rewind
它将重置为 1。或者如果您想重置全部。
这是 github 上文件的链接
There is a class method called
sequence_by_name
to fetch a sequence by name, and then you can callrewind
and it'll reset to 1.Or if you want to reset all.
Here is the link to the file on github
经过我对源码的摸索,终于找到了解决方案。如果您使用的是factory_girl 1.3.2(这是我撰写本文时的最新版本),您可以将以下代码添加到factories.rb文件的顶部:
然后,在Cucumber的env.rb中,只需添加:
我假设如果您在 rspec 测试中遇到同样的问题,您可以在 :each 方法之后使用 rspecs 。
目前,这种方法只考虑工厂内定义的序列,例如:
我还没有编写代码来处理:Factory.sequence...
After tracing my way through the source code, I have finally come up with a solution for this. If you're using factory_girl 1.3.2 (which was the latest release at the time I am writing this), you can add the following code to the top of your factories.rb file:
Then, in Cucumber's env.rb, simply add:
I'd assume if you run into the same problem in your rspec tests, you could use rspecs after :each method.
At the moment, this approach only takes into consideration sequences defined within a factory, such as:
I have not yet written the code to handle: Factory.sequence...
对于谷歌搜索的人:无需进一步扩展,只需
上为我工作
在https://stackoverflow.com/
FactoryGirl.reload
a/16048658For googling people: without further extending, just do
FactoryGirl.reload
works for me on
https://stackoverflow.com/a/16048658
根据 ThoughBot 这里< /a>,需要重置测试之间的顺序是一种反模式。
总结:
如果您有这样的事情:
您的测试应该如下所示:
不是这样:
According to ThoughBot Here, the need to reset the sequence between tests is an anti-pattern.
To summerize:
If you have something like this:
Your tests should look like this:
Not This:
必须确保序列从 1 到 8,然后重新启动到 1,依此类推。像这样实现:
doc 说“该值只需要支持
#next
方法。”但为了让 CustomSequence 对象继续运行,它也需要支持#peek
方法。最后我不知道这会工作多久,因为它有点侵入 FactoryGirl 的内部,当他们做出改变时,这可能无法正常工作Had to ensure sequences are going from 1 to 8 and restart to 1 and so on. Implemented like this:
The doc says "The value just needs to support the
#next
method." But to keep you CustomSequence object going through it needs to support#peek
method too. Lastly I don't know how long this will work because it kind of hack into FactoryGirl internals, when they make a change this may fail to work properly没有内置的方法来重置序列,请参阅此处的源代码:
http://github.com/thoughtbot/factory_girl/blob/master/lib/factory_girl/sequence.rb
但是,有些人已经破解/猴子修补了此功能。这是一个示例:
http://www.pmamediagroup.com/2009/05/smarter-工厂女孩测序/
There's no built in way to reset a sequence, see the source code here:
http://github.com/thoughtbot/factory_girl/blob/master/lib/factory_girl/sequence.rb
However, some people have hacked/monkey-patched this feature in. Here's an example:
http://www.pmamediagroup.com/2009/05/smarter-sequencing-in-factory-girl/
要重置特定序列,您可以尝试
To reset particular sequence you can try
如果您使用 Cucumber,则可以将其添加到步骤定义中:
然后在需要时调用它。
If you are using Cucumber you can add this to a step definition:
Then just call it when needed.