LauraBeatris

LauraBeatris

I’m still in a learning phase regarding testing in Elixir, and yesterday I was trying to understand the common patterns to mock built-in modules

I have the following module + function:

defmodule FizzBuzz do
  def build(file_name) do
    file_name
    |> File.read()
    |> process_file_result
  end

And in the test, I’d like to mock the File.read result in order to not have to read from my filesystem:

 describe("build/1") do
    test "when a valid file is provided, returns the converted list" do
      expected_response = {:ok, [2, :buzz, :buzz, :fizzbuzz, :buzz, :buzz]} 
      assert FizzBuzz.build("numbers.txt") == expected_response
    end

I searched for a couple of libraries and found Mox, can it be used for that purpose?

Showing Posts 1 to 10

mayel

mayel

You could use the mock library

tfwright

tfwright

Yes a very common pattern is to create your own API for “file reading functions”, use that instead of File directly, and then you can mock your API in tests as covered in this post

al2o3cr

al2o3cr

I’m probably missing some nuance due to the example being generic, but it sounds like what you want is a test of process_file_result, not one for build:

  • you want to set an input string for it during test setup
  • you want to inspect the output

No mocks needed in that case…

sodapopcan

sodapopcan

Even though it’s the opposite of what you asked, if you ever find yourself wanting to test against the file system, ExUnit has a handy tmp_dir solution.

You can definitely use Mox, though. I’ve also heard good things about Patch if you want a possibly more familiar option (depending on what ecosystem you’re used to).

LauraBeatris

LauraBeatris OP

Yeah, that makes sense

process_file_result already defines some guards depending on the File.read result, with that said, I could also only test that function without needing to rely on build

defp process_file_result({:error, reason}),
    do: {:error, "Error while reading the file: #{reason}"}

  defp process_file_result({:ok, content}) do

The only implementation detail there is that process_file_result is a private function, and build is the only one public, but I do understand your point!

LauraBeatris

LauraBeatris OP

Thanks for all the references! If I could ask one more thing, what are the use cases for tmp_dir in production-level codebases?

Also, Patch seems pretty cool! More similar to what I’m used to in the TypeScript world

sodapopcan

sodapopcan

It’s good for scenarios where the main purpose is to write to disk and you want to test reality without mocks. I do top-down TDD and I write very little code that writes to disk, so I feel better about taking the small hit on testing speed and testing what’s actually going to happen as opposed to bring in mocks. YMMV, of course, I don’t work on particularly massive systems or anything. I’m also using it for an image generation service where I want to write out the result and compare it to the expected image not just programmatically but visually as well.

krasenyp

krasenyp

Everyone before me gave good suggestions. I wouldn’t use mocks for this test. I also generally prefer stubs. Mocks are very tricky because they test interaction. In your case this is the call to File.read. If you at some point, hypothetically, use a different function for reading, your test will be broken.

tfwright

tfwright

This is not necessarily true of Mox at least, it’s part of the “mocks as nouns” rule. By creating your own mock API that is used locally (in the specific logic you want to mock) rather than globally you create more intentional boundaries that are less fragile.

LauraBeatris

LauraBeatris OP

Could you clarify on stubs here? Stubs for me in the Node.js ecosystem are when HTTP requests are intercepted

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 92995 915
New
AstonJ
The obligatory hello world thread! Who are you and where are you from? :stuck_out_tongue:
4616 55835 594
New
caslu
I want to open this thread for you all to discuss and help those who really like Ash but are still hesitant to use it in a real project. ...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
Herve37
We’re evaluating API mocking tools for OpenAPI-based projects and would love to hear what other teams are using. We’re particularly inte...
New
GES233
I’m posting this in response to Jose’s recent tweet (Cr. link) : People are sleeping on Elixir for a coding harness: Hot-code swappi...
New
nseaSeb
AcmeScript — Writing JS hooks as if I were still using Elixir I’ve been having fun building a little something over the last few days: Ac...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New
webofbits
Aludel - LLM Evaluation Workbench Aludel is an embeddable Phoenix LiveView dashboard for evaluating and comparing LLM prompts across mult...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews