Testing an elixir function using Mock

I have a Product schema which has a UPI(unique product identifier) eg. A985748BNG6784C . This is an autogenerated unique product identifier.

I have a function upi_generate() which calls another external function gen_nano_id() to generate this random unique id.

If by chance, the id generated by gen_nano_id() has already been generated, the function upi_generate() calls itself recursively till the time gen_nano_id() generates a unique id. Thus generating a unique UPI .

gen_nano_id() can sometimes return duplicate ids and for that purpose I have written the below code with recursive call.

  def gen_nano_id() do  #external function
      Nanoid.generate(10, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
  end

  # TODO: write test case for this
  def upi_generate() do # required function
      upi = "A" <> gen_nano_id() <> "C"

      case get_product_with_upi(upi) do
         nil ->
            upi 
         _ ->
            upi_generate()
      end
  end

  # Check if product with upi already exists
  defp get_product_with_upi(upi) do
      from(p in "snitch_products", select: p.upi, where: p.upi == ^upi) 
      |> Repo.one()
  end

Now, I have to test the id regeneration logic for duplicate ids.

My testing approach involves following logic. Create two products with duplicate UPI and try to reach the _ part of the case comparison.

For this purpose, I have mocked(I don’t control the behaviour of this function) the gen_nano_id() .

Now, the problem that I am facing is mocking results in creation of always the same ids no matter what and I go in an infinite loop.

I am not able to figure out a way to reach the exit condition(nil) part of case comparison with this mocking approach of gen_nano_id .