如何使用FactoryBot重用类似属性的代码?

时间:2018-01-23 04:36:08

标签: ruby-on-rails factory-bot

我说两个模型@Extension( name = "mqtt", namespace = "source", description = "The MQTT source receives the events from an MQTT broker ", parameters = {@Parameter( name = "url", description = "The URL of the MQTT broker. It is used to connect to the MQTT broker. It is required to specify a valid URL here.", type = {DataType.STRING} ), @Parameter( name = "username", description = "The username to be provided when the MQTT client is authenticated by the broker.", type = {DataType.STRING}, optional = true, defaultValue = "null" ), @Parameter( name = "password", description = "The password to be provided when the MQTT client is authenticated by the broker.", type = {DataType.STRING}, optional = true, defaultValue = "empty" ), @Parameter( name = "client.id", description = "A unique ID for the MQTT client. The server uses this to identify the client when it reconnects. If you do not specify a client ID, the system automatically generates it.", type = {DataType.STRING} ), @Parameter( name = "topic", description = "The topic from which WSO2 SP receives events via MQTT. Multiple topics can be specified as a list of comma separated values.This is a mandatory parameter.", type = {DataType.STRING} ), @Parameter( name = "quality.of.service", description = "The quality of service provided by the MQTT client. The possible values are as follows.`0`: The MQTT client sends each event to WSO2 SP only once. It does not receive an acknowledgement when an event is delivered, and the events are not stored.Events may get lost if the MQTT client is disconnected or if the server fails.This is the fastest method in which events are received via MQTT.`1`: The MQTT client sends each event to WSO2 SP at least once. If the MQTT client does not receive an acknowledgement to indicate that the event is delivered, it sends the event again.`2`: The MQTT client sends each event to WSO2 SP only once. The events are stored until the WSO2 SP receives them. This is the safest, but the slowest method of receiving events via MQTT.", type = {DataType.STRING}, optional = true, defaultValue = "1" ), @Parameter( name = "clean.session", description = "This is an optional paramater. If this parameter is set to `true`, the subscriptions made by the MQTT client during a session expire when the session ends,and they need to be recreated for the next session.\nIf this parameter is set to `false`, all the information relating to the MQTT client's connection to the broker (e.g., the specific topics to which the client has subscribed) are saved after a session. Thus, when a session ends and restarts, the connection is re-established with the same information.\nThe default value is `true`.", type = {DataType.BOOL}, optional = true, defaultValue = "true" ), @Parameter( name = "keep.alive", description = "The maximum number of seconds the connection between the MQTT client and the broker should be maintained without any events being transferred. Once this time interval elapses without any event transfers, the connection is dropped. The default value is 60.", type = {DataType.INT}, optional = true, defaultValue = "60" ), @Parameter( name = "connection.timeout", description = "The maximum number of seconds that the MQTT client should spend attempting to connect to the MQTT broker. Once this time interval elapses, a timeout takes place.", type = {DataType.INT}, optional = true, defaultValue = "30" )}, Person都是不同的模型,但它们都有一个共同的属性:Company。如果我使用FactoryBot,我将按如下方式实施各自的工厂:

address

有没有办法可以定义一个FactoryBot.define do factory :person do # ... address { Faker::Address.street_address } end end FactoryBot.define do factory :company do # ... address { Faker::Address.street_address } end end ,我可以从工厂内的任何地方调用它?例如:

address generator

目前,我可以使用# define reusable attribute FactoryBot.define do attribute :address { Faker::Address.street_address } end FactoryBot.define do factory :person do # ... generate_attribute(:address) end end FactoryBot.define do factory :company do # ... generate_attribute(:address) end end 复制此期望的行为,但似乎它们并不适用于此任务。

2 个答案:

答案 0 :(得分:2)

如果你想在工厂内的任何地方使用一个函数,你可以创建一个spec帮助器并定义你在那里的功能:

# AppSpecHelper
# spec/support/app_spec_helper
module AppSpecHelper
  def generate_attribute
    ...
  end
end

RSpec.configure do |c|
  c.include AppSpecHelper
end

rails_helper.rb

RSpec.configure do |config|
  config.include AppSpecHelper
end

答案 1 :(得分:1)

我认为您可以为工厂指定一个零级别,这样可以让您拥有这两个工厂的共同父级:

factory :addressable, class: nil do
  address { Faker::Address.street_address }
end

factory :person, parent: :addressable do
  ...
end

factory :company, parent: :addressable do
  ...
end