param being a list of an entity #4
-
Say I want to create a |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
In general, I avoid inserting a list of something by default, as the more data in the DB - the slower tests are. But let's look at a couple of approaches.
# schema
command :create_blog do
resolve(...)
produce :blog
end
command :create_post do
param :blog, entity: :blog
resolve(...)
produce :post
end
# usage
ctx
|> produce(:blog)
|> produce(post: :post1)
|> produce(post: :post2)
param :post_params, generate: fn -> [%{text: random_text()}, %{text: random_text()}] end
param :post_author, entity: :author
resolve(fn args ->
post_params = Enum.map(args.post_params, &Map.put(&1, author: args.post_author))
...
end) The downside of this approach is that you cannot put each post separately to the context using
command :create_blog do
param :post do
param :text, generate: &random_text/0
end
param :author, entity: :author
resolve(fn args ->
blog = MyApp.create_blog!(args.author)
post = MyApp.create_post!(blog, args.post, args.author)
{:ok, %{blog: blog, post: post}}
end)
produce :blog
produce :post
end
command :add_post_to_blog do
param :blog, entity: :blog
param :text, generate: &random_text/0
resolve(fn args ->
post = MyApp.create_post!(args.blog, %{text: args.text}, args.author)
{:ok, %{post: post}}
end)
produce :post
end
# usage
ctx
|> produce([:blog, post: :post1])
|> rebind([post: :post2], &exec(:add_post_to_blog)) This approach is convenient if you always need a # schema
...
trait :additional, :post do
exec :add_post_to_blog
end
# usage
ctx
|> produce([:blog, post: :post1])
|> produce(post: [:additional, as: :post2])
# schema
command :create_email do
param :sender, entity: :admin
param :to_recipient, entity: :user
param :other_to_recipients, generate: fn -> [] end
resolve(fn args ->
email = MyApp.save_email!(%{sender: args.sender, to_recipients: [args.to_recipient | args.other_to_recipients]})
{:ok, %{email: email}}
end)
produce :email
end
# usage
produce(ctx, :email) # produces admin, email and user.
# if you need more recipients, then use exec/3 and pass them explicitly
%{user: boss} = produce(ctx, :user)
exec(ctx, :create_email, other_to_recipients: [boss])
command :init_uninvoiced_line_item_ids do
resolve(fn _ ->
{:ok, %{uninvoiced_line_item_ids: []}}
end)
produce :uninvoiced_line_item_ids
end
command :create_line_item_for_cucumber do
parma :cucumber, entity: :cucumber
param :uninvoiced_line_item_ids, entity: :uninvoiced_line_item_ids
resolve(fn args ->
line_item = MyApp.create_line_item(args.cucumber)
{:ok,
%{
line_item_for_cucumber: line_item,
uninvoiced_line_item_ids: [line_item.id | args.uninvoiced_line_item_ids]
}}
end)
produce :line_item_for_cucumber
end
command :create_line_item_for_potato do
parma :potato, entity: :potato
param :uninvoiced_line_item_ids, entity: :uninvoiced_line_item_ids
resolve(fn args ->
line_item = MyApp.create_line_item(args.potato)
{:ok,
%{
line_item_for_potato: line_item,
uninvoiced_line_item_ids: [line_item.id | args.uninvoiced_line_item_ids]
}}
end)
produce :line_item_for_potato
end
command :create_invoice do
param :uninvoiced_line_item_ids, entity: :uninvoiced_line_item_ids
resolve(fn args ->
invoice = MyApp.create_invoice(args.uninvoiced_line_item_ids)
{:ok, %{invoice: invoice, uninvoiced_line_item_ids: []}}
end)
update :uninvoiced_line_item_ids
produce :invoice
end
# usage
# create invoice with 1 associated line item
ctx
|> produce(:line_item_for_cucumber)
|> produce(:invoice)
# create invoice with 3 associated line items
ctx
|> produce(:line_item_for_cucumber)
|> produce(:line_item_for_potato: :li_for_potato1, potato: :potato1)
|> produce(:line_item_for_potato: :li_for_potato2, potato: :potato2)
|> produce(:invoice) Hope it helps. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the thorough list of options. I'll certainly have to ponder a bit on those options. I can see the idea behind the first one, but I currently don't allow what would be the blog in this example to be created without posts. So I cannot really do step by step creation. The idea of having each entity somewhat identifiable is certainly powerful, but also might become tedious. I think for now I'll go with I've a bunch of has_many associations to deal with, so I guess I'll have to see how things go and try out what you suggested. |
Beta Was this translation helpful? Give feedback.
In general, I avoid inserting a list of something by default, as the more data in the DB - the slower tests are. But let's look at a couple of approaches.
generate
option which generates a list of params. This should work fine if you can generate all data points with faker/etc and other entities (associations) are not required. However, even if posts require othe…