tutorial sheet rails has_many factorybot create cheat bot association ruby-on-rails-3 rspec factory-bot

ruby-on-rails-3 - sheet - factorybot create



¿Cómo definir una matriz/hash en Factory Girl? (5)

Estaba interesado en hacer lo mismo, también para probar un modelo mío que funciona utilizando un hash de contenido de una API de terceros. Descubrí que al usar algunas de las funciones integradas de factory_girl, pude construir estas estructuras de datos de forma limpia.

Aquí hay un ejemplo artificial:

factory :chicken, class:Hash do name "Sebastian" colors ["white", "orange"] favorites {{ "PETC" => "http://www.petc.org" }} initialize_with { attributes } end

El truco principal aquí es que cuando declaras initialize_with, factory_girl ya no intentará asignar los atributos al objeto resultante. También parece omitir la tienda de db en este caso. Entonces, en lugar de construir algo complicado, simplemente pasamos el hash de atributo ya preparado como nuestro contenido. Voila.

Parece necesario especificar algún valor para la clase, a pesar de que en realidad no se está utilizando. Esto es para evitar que factory_girl intente crear una instancia basada en el nombre de la fábrica. He elegido usar clases descriptivas en lugar de Object, pero depende de usted.

Todavía puede sobrescribir los campos cuando usa una de estas fábricas de hash:

chick = FactoryGirl.build(:chicken, name:"Charles")

... sin embargo, si ha anidado el contenido y desea anular los campos más profundos, necesitará aumentar la complejidad del bloque de inicialización para hacer una especie de fusión profunda.

En su caso, está usando algunos datos mezclados y hash, y parece que la propiedad Path debería reutilizarse entre partes de la estructura de datos. No hay problema: conoce la estructura del contenido, por lo que puede crear fácilmente una fábrica que construya la matriz resultante correctamente. He aquí cómo podría hacerlo:

factory :dropbox_hash, class:Array do path "/home" revision 48 rev "30054214dc" thumb_exists false bytes 0 modified { 3.days.ago } is_dir true icon "folder_app" root "app_folder" size "0 bytes" initialize_with { [ attributes[:path], attributes ] } end FactoryGirl.build(:dropbox_hash, path:"/Chickens", is_dir:false)

También puede omitir valores innecesarios. Imaginemos que solo Path y rev son realmente necesarios:

factory :dropbox_hash, class:Array do path "/home" rev "30054214dc" initialize_with { [ attributes[:path], attributes ] } end FactoryGirl.build(:dropbox_hash, path:"/Chickens", revision:99, modified:Time.now)

Estoy intentando escribir una prueba que simule algunos valores de retorno del servicio REST de Dropbox que me devuelve datos en una matriz, con un hash anidado.

Tengo problemas para descifrar cómo codificar mi fábrica, ya que el resultado de la devolución es una matriz con una dentro. ¿Qué iría aquí?

Factory.define :dropbox_hash do ?? end

Los datos de Dropbox se ven así:

["/home", {"revision"=>48, "rev"=>"30054214dc", "thumb_exists"=>false, "bytes"=>0, "modified"=>"Thu, 29 Dec 2011 01:53:26 +0000", "path"=>"/Home", "is_dir"=>true, "icon"=>"folder_app", "root"=>"app_folder", "size"=>"0 bytes"}]

Y me gustaría una llamada de fábrica como esta en mi RSpec:

Factory.create(:dropbox_hash)


Esto funcionó para mí, y puedo pasar atributos según sea necesario en el hash

factory :some_name, class:Hash do defaults = { foo: "bar", baz: "baff" } initialize_with{ defaults.merge(attributes) } end > build :some_name, foo: "foobar" #will give you > { foo: "foobar", baz: "baff" }


Puedes hacer esto en las últimas versiones de factory_girl, pero es incómodo porque está diseñado para construir objetos y no estructuras de datos. Aquí hay un ejemplo:

FactoryGirl.define do factory :dropbox_hash, :class => ''Object'' do ignore do url { "/home" } revision { 48 } rev { "30054214dc" } # more attributes end initialize_with { [url, { "revision" => revision, "rev" => rev, ... }] } to_create {} end end

Repasando las cosas raras aquí:

  • Cada fábrica necesita una clase de compilación válida, incluso si no se utiliza, así que pasé Object aquí para evitar que busque DropboxHash .
  • array.revision = 48 ignorar todos los atributos utilizando un bloque de ignore para que luego no intente asignarlos a la matriz, como array.revision = 48 .
  • Puedes decirle cómo juntar tu resultado usando initialize_with . La desventaja aquí es que necesita escribir de nuevo la lista de atributos completa.
  • ¡ to_create proporcionar un bloque to_create vacío para que no intente llamar a array.save! después.

Un seguimiento de la versión actual de RSpec (3.0):

Simplemente defina su fábrica como siempre y use FactoryGirl.attributes_for para recibir un hash en lugar de una clase instanciada.


Usé OpenStruct:

factory :factory_hash, class:OpenStruct do foo "bar" si "flar" end

Editar: lo siento, no funciona como un hash

Finalmente uso una versión estática, solo para mantener ese hash proveniente del sistema Factory ...

factory :factory_hash, class:Hash do initialize_with { { foo "bar" si "flar" } } end

buscando algo mejor