Nitpick for the first example, I think you can completely side-step problem with the magic number by using the product price, like the test said it would
test "uses the product price as the order total", %{
customer: customer,
product: product
} do
assert {:ok, order} = Orders.create(customer, product)
assert order.total == product.price
end
wrt to large, shared setup blocks like the one in your example
setup do
account = insert(:account)
admin = insert(:user, role: :admin, account: account)
employee = insert(:user, role: :employee, account: account)
subscription = insert(:subscription, account: account)
product = insert(:product)
%{
account: account,
admin: admin,
employee: employee,
subscription: subscription,
product: product
}
end
Elixir already provides tools that make it possible to balance the of setup blocks
Setup functions can be changed
Instead of writing one large block you can build composable setup blocks. for example
setup [:with_account, :with_role, :with_subscription, :with_product]
Then define the setup blocks
def with_account(_context) do
{:ok, account: insert(:account)}
end
def with_subscription(context) do
{:ok, subscription: insert(:subscription, account: account)}
end
Using tags to modify setups per test
using @tag we can inject some values into the context ourselves, which we can use to modify shared setups to the needs of the test.
def with_product(context) do
{:ok, product: insert(:product, Map.get(context, :product_data, %{}))
end
Using these features the first test could be rewritten like this, allowing you to keep the tests (Not that I recommend this in particular, because using the product price directly would be preferred)
@tag product_data: %{price: 1000}
test "uses the product price as the order total", %{
customer: customer,
product: product
} do
assert {:ok, order} = Orders.create(customer, product)
assert order.total == 1000
end
I do not disagree with the points presented, but I prefer the ability to compose and to extend when possible. Also dicipline your Agents early on with DRY or else you’ll find the same function 5 times in different places and with different names.