How to test this using mock?

I have a function something like this

 def update do
    {:ok, users} = Restaurant.load_user_transactions()

    users
    |> Enum.map(&load_restaurant_order/1)
    |> Enum.map(&update_order/1)
  end

So first here load_user_transactions() will load all the id for the users. Then with that list of users, I’m loading the corresponding restaurant orders and in the end, I’m updating some fields in the users table.

So I have written a unit test case like this

test "update" do
    users = [
              %User{
                   id: 1, 
                   name: "max", 
                   description: "maaxx"
              }
                ]
    expect(UserDomainMock, :load_user_transactions, fn -> {:ok, users} end)

    restaurants = RestaurantMock.payment_order()
    expect(RestaurantMock, :load_restaurant_order, fn _ -> {:ok, restaurants} end)

    expect(RestaurantMock, :update_order, fn _, _ -> {:ok, nil} end)

    assert TransactionUpdate.load()
  end

1 . here load_user_transactions expect list of users id.
2. Then the id will be passed on load_restaurant_order
3. Then it will update some fields here update_order

Is anything loaded over an API? I would create a mock for these modules. The rest I wouldn’t even mock and verify that correct data was inserted in the DB.

If these are in the database then I would recommend using the Ecto Sandbox instead: Ecto.Adapters.SQL.Sandbox — Ecto SQL v3.7.1

If you did want to use Mock then I think you have done it appropriately, but I would say that with that amount of mocking you’ve created a very brittle test that isn’t buying you much.

3 Likes

To expand on @axelson’s answer: do read about Mox and the linked article; consider changing your approach to testing - it looks like you’re testing the implementation instead of the actual behavior.

thanks. Let me check sandbox. looks interesting

okay thanks