spinlock99

spinlock99

I always wind up not having private functions in my modules because you can’t test them. I really have a strong preference for TDD and - at this point - I can barely write a function without having a test first. I recently had a function that is stupid simple:

def char_value(char), do: char - ?@

The point is to convert an uppercase letter to a numerical value (i.e. A == 1, B == 2, etc…). This is just a helper function that I’d never want to expose outside of the module, it’s logic is very simple, but It was tricky (for me) to figure out that ?@ == 64 and gave me the value I want. I suppose I could have just made the function char - ?A + 1 but this is just an example of when a function (which should be private IMO) benefits from being tested.

Am I just thinking about private functions wrong? To me, a private function is a helper for simplifying the complexity of public functions in the module. Should I just think of private functions as functions that are themselves simple enough to not need a test?

Most Liked

sodapopcan

sodapopcan

You could start a holy war with questions like this! :upside_down_face:

I’m a TDDer myself and I do not see value in testing private functions in that they mostly appear later as I’m refactoring. However, sometimes you can find yourself with a single function that does a lot of stuff. In those cases, you can always move these function to a sub “private” module (@moduledoc false) and write tests for them there (though personally when I do this I just end up deleting the tests when I’m done as I just want tests for my public interface).

In the case of your example, that is a candidate to just be moved to an external helper module. It’s one of those functions that does one small thing very well, so there’s no harm in other people using it, especially since it has tests! However, if you really want to keep it private in your current module, then the tests for whatever public function you are using this for will certainly cover it. If you really want to start with just a test for that one line, then I’d do what I suggested above (and sanctioned by Sandi Metz herself ;)), make it public, write a test for it and when you’re done, or at least when you have public functions that consume it, delete the test and make it private.

Otherwise, keeping tests for things at this level of granularity makes reafactorting a massive pain. It’s also exhausting for readers (although I guess no one reads code anymore and LLMs don’t get exhausted /s)

tfwright

tfwright

I don’t think this is unquestionably true. Maybe debatable, but I’d strongly argue that one of the underrated benefits of unit tests is that they document what a module does. If you maintain tests for private functions you are now also documenting how it does it. Not terrible, but why do that when you can write a test for the caller than exercises the private function?

dimitarvp

dimitarvp

Private functions to me should be:

  • An implementation detail;
  • A way to enforce boundaries.

If you find yourself needing to test private functions then it’s time to ask yourself or the team these questions:

  • Is it time to promote these functions into a public API and accept that any other module in the app can call them now?
  • Are you getting obsessive about testing every single thing? Indeed testing the public API and letting a private function fail an assertion as a part of that test is quite fine and not a reason to make private functions public.

I don’t agree with the argument that only libraries should carefully control what’s public. I’m currently working hard, together with Claude, to untangle quite the spaghetti code. It’s painful and it really drives home the point that scope and access creep are real problems.

Last Post!

Asd

Asd

Unused private functions are not compiled in the module, therefore Repatch cant access their code to make them public in tests. Try using this private function in a public one

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 94592 917
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
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
heathen
Quite interesting article Google brought me. Didn’t find any mentions about it here. What do you think in general? Would you use togethe...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
axelson
Hi there! :wave: @frigidcode and I (but mostly him) have been running an Elixir Book club, we’re almost done with Designing Elixir Syste...
New
AstonJ
Since we have deprecated our Erlang sections (as we have dedicated Erlang Forums now) let’s add this thread for those who’d like to post ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews