Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot create a mock function with the same arity as the original function definition #86

Open
sillidev opened this issue Nov 28, 2024 · 1 comment

Comments

@sillidev
Copy link

Hi,

I had below code (got it from Phoenix tutorial) and I used Mimic to simulate Repo.transaction() result

  alias MyApp.Repo

  def complete_order(%ShoppingCart.Cart{} = cart) do
    line_items =
      Enum.map(cart.items, fn item ->
        %{product_id: item.product_id, price: item.product.price, quantity: item.quantity}
      end)

    order =
      Ecto.Changeset.change(%Order{},
        user_uuid: cart.user_uuid,
        total_price: ShoppingCart.total_cart_price(cart),
        line_items: line_items
      )

    Ecto.Multi.new()
    |> Ecto.Multi.insert(:order, order)
    |> Ecto.Multi.run(:prune_cart, fn _repo, _changes ->
      ShoppingCart.prune_cart_items(cart)
    end)
    |> Repo.transaction()
    |> case do
      {:ok, %{order: order}} -> {:ok, order}
      {:error, name, value, _changes_so_far} -> {:error, {name, value}}
    end
  end

If I mock transaction/2, I will get error MyApp.Repo.transaction/2 to be invoked 1 time(s) but it has been called 0 time(s)

MyApp.Repo
      |> expect(:transaction, fn _x, _y -> {:error, "mock", "this is mock error for testing", %{}} end)

However, it works well if I try transaction/1 instead

MyApp.Repo
      |> expect(:transaction, fn _x -> {:error, "mock", "this is mock error for testing", %{}} end)

Is it desired behavior? I expect to mock transaction as arity of 2 which matches its definition.

@edgurgel
Copy link
Owner

edgurgel commented Dec 8, 2024

The thing is that you are calling transaction/1 with a multi in your example. So you must stub/expect on transaction/1. transaction/2 will only be called when options are passed in. Ecto.Repo simply defaults to [] if the second argument is not passed.

The link you passed is the callback definition not the actual Repo definition:

https://github.com/elixir-ecto/ecto/blob/18288287f18ce205b03b3b3dc8cb80f0f1b06dbe/lib/ecto/repo.ex#L282C26-L282C53

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants