<instructions>Your goal is to analyze the following comment and estimate how highly it will be upvoted by the Hacker News community.</instructions><comment><author>thibaut_barrere</author><text>&amp;gt; Mox is nothing more than a kludge to get around the limitations of the language and I think there are much less invasive kludges available. To be honest when I’m working with devs who are new to elixir I’m embarrassed when I have to explain how Mox works.&lt;p&gt;There are other ways, more similar to Ruby etc (e.g. &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;edgurgel&amp;#x2F;mimic&quot;&gt;https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;edgurgel&amp;#x2F;mimic&lt;/a&gt;, or with_mock etc).&lt;p&gt;And also there is the risk to &amp;quot;over-mock&amp;quot;, for sure.&lt;p&gt;But a good middle ground brings the right value here!</text><parent_chain><item><author>sarchertech</author><text>I hope you see the irony in using “you’re holding it wrong” here?&lt;p&gt;If real world use of a library tends to push towards a certain outcome that I dislike, I’m going to tend to dislike that library.&lt;p&gt;You’re also never going to convince me that creating an interface for a single implementation is the best way to facilitate unit testing.&lt;p&gt;Mox is nothing more than a kludge to get around the limitations of the language and I think there are much less invasive kludges available. To be honest when I’m working with devs who are new to elixir I’m embarrassed when I have to explain how Mox works.&lt;p&gt;&amp;gt;but in practice it&amp;#x27;s better to hardcode things rather than trying to make it generic and swappable the first time around. Junior devs have a tendency to over-engineer code &amp;quot;because we might need to change it later.&amp;quot; My motto is &amp;quot;copy and paste it three times before adding a layer of abstraction&amp;quot;&lt;p&gt;This I agree with 100%</text></item><item><author>sph</author><text>That just means you&amp;#x27;re putting a boundary when it&amp;#x27;s not necessary. Mox exists to make tests simpler to write and reason about, if you keep hitting extra layers of indirections then, &amp;quot;you&amp;#x27;re holding it wrong.&amp;quot;&lt;p&gt;Most things are best used sparingly. That said, the vast majority of developers, even senior, have a very limited understanding of testing practices, and tend to create millions of separated, isolated modules, for no reason whatsoever. That&amp;#x27;s not Mox&amp;#x27;s fault.&lt;p&gt;A stupid example in practice: a naive blog app does not need Mox at all. If you add SSO sign up, you might want to put a boundary there to unit test without needing to set up a fake auth server, but 99% of your code won&amp;#x27;t ever touch it, just the authentication tests. Tomorrow you add payments, you might want to put a boundary just before your &lt;i&gt;StripeRestAPI&lt;/i&gt; module to test the entire payment flow without contacting Stripe in your unit tests. Again, only the payment module tests ever need to touch Mox, the rest of your code doesn&amp;#x27;t. You place it before modules in the outer edge that have real-world side effects, not to isolate your functional and mostly pure core.&lt;p&gt;I recommend the DestroyAllSoftware talks, especially &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;www.destroyallsoftware.com&amp;#x2F;talks&amp;#x2F;boundaries&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;www.destroyallsoftware.com&amp;#x2F;talks&amp;#x2F;boundaries&lt;/a&gt;&lt;p&gt;&amp;gt; And I just can’t justify it with “one day I might want to swap out the implementation”. YAGNI and if you do, deal with it then.&lt;p&gt;I agree with that. Using Mox to swap out implementations is a possible use case, but in practice it&amp;#x27;s better to hardcode things rather than trying to make it generic and swappable the first time around. Junior devs have a tendency to over-engineer code &amp;quot;because we might need to change it later.&amp;quot; My motto is &lt;i&gt;&amp;quot;copy and paste it three times before adding a layer of abstraction&amp;quot;&lt;/i&gt;</text></item><item><author>sarchertech</author><text>I hate Mox with a passion. Because I hate separating out the interface and implementation of something that is only ever going to have one real implementation.&lt;p&gt;The extra layer of indirection just for testing bugs me so much. And I just can’t justify it with  “one day I might want to swap out the implementation”. YAGNI and if you do, deal with it then.&lt;p&gt;So much legacy elixir code is an unreadable mess because of all the extra layers of interfaces that only get used for Mox. There’s nothing I dislike more than diving into an unfamiliar section of code and having to keep 15 files open to follow the logic for something that should have been in one module.</text></item><item><author>sph</author><text>Seconding the Mox recommendation, it&amp;#x27;s pretty good and enforces good separation of concerns in your application. It was created by José himself, so you know it&amp;#x27;s got a well-designed API. You just need to get used with using behaviours, and using the Application config to tell your code when to use the mock vs the real thing.&lt;p&gt;I use it to separate and test external API calls (i.e. to test the payment layer without making any request), to maintain separation between my code and an external library I might want to swap out at a later date, or even between various components of the application. Then writing unit tests becomes a breeze, and you don&amp;#x27;t need many integration tests.&lt;p&gt;&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;hexdocs.pm&amp;#x2F;mox&amp;#x2F;Mox.html&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;hexdocs.pm&amp;#x2F;mox&amp;#x2F;Mox.html&lt;/a&gt;</text></item><item><author>thibaut_barrere</author><text>Good write-up!&lt;p&gt;I will add:&lt;p&gt;- make sure to “stream” your transfers in general, instead of keeping whole file blobs in RAM. This to avoid refactoring at the least comfortable moment when a file gets too big in production&lt;p&gt;- it is quite easy to use Mox for isolated testing in general, and it works nicely with ExAws, so make sure to integrate those tests early on</text></item></parent_chain></comment><story><title>Fundamentals of Object Storage in Elixir</title><url>https://underjord.io/fundamentals-of-object-storage.html</url></story>
<instructions>Your goal is to analyze the following comment and estimate how highly it will be upvoted by the Hacker News community.</instructions><comment><author>sph</author><text>&amp;gt; I hope you see the irony in using “you’re holding it wrong” here?&lt;p&gt;Not really. If you use a hammer on a screw, is it the hammer&amp;#x27;s fault? Sounds like the code base you are working on is badly-organised, rather than Mox being the root of all evil. There are far too many stories of people picking up Elixir and coding in it as if it were Python or Ruby. You cannot base your experience with it on a codebase written by people new to functional languages.&lt;p&gt;And no one forces you to use Mox, anyway. It&amp;#x27;s far from being a core Elixir component. It is just &lt;i&gt;one&lt;/i&gt; implementation of the mock object pattern that comes on a standalone, optional library.&lt;p&gt;&amp;gt; Mox is nothing more than a kludge to get around the limitations of the language&lt;p&gt;Mocks are not an Elixir invention, and exist in pretty much all languages.&lt;p&gt;&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;en.wikipedia.org&amp;#x2F;wiki&amp;#x2F;Mock_object&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;en.wikipedia.org&amp;#x2F;wiki&amp;#x2F;Mock_object&lt;/a&gt;</text><parent_chain><item><author>sarchertech</author><text>I hope you see the irony in using “you’re holding it wrong” here?&lt;p&gt;If real world use of a library tends to push towards a certain outcome that I dislike, I’m going to tend to dislike that library.&lt;p&gt;You’re also never going to convince me that creating an interface for a single implementation is the best way to facilitate unit testing.&lt;p&gt;Mox is nothing more than a kludge to get around the limitations of the language and I think there are much less invasive kludges available. To be honest when I’m working with devs who are new to elixir I’m embarrassed when I have to explain how Mox works.&lt;p&gt;&amp;gt;but in practice it&amp;#x27;s better to hardcode things rather than trying to make it generic and swappable the first time around. Junior devs have a tendency to over-engineer code &amp;quot;because we might need to change it later.&amp;quot; My motto is &amp;quot;copy and paste it three times before adding a layer of abstraction&amp;quot;&lt;p&gt;This I agree with 100%</text></item><item><author>sph</author><text>That just means you&amp;#x27;re putting a boundary when it&amp;#x27;s not necessary. Mox exists to make tests simpler to write and reason about, if you keep hitting extra layers of indirections then, &amp;quot;you&amp;#x27;re holding it wrong.&amp;quot;&lt;p&gt;Most things are best used sparingly. That said, the vast majority of developers, even senior, have a very limited understanding of testing practices, and tend to create millions of separated, isolated modules, for no reason whatsoever. That&amp;#x27;s not Mox&amp;#x27;s fault.&lt;p&gt;A stupid example in practice: a naive blog app does not need Mox at all. If you add SSO sign up, you might want to put a boundary there to unit test without needing to set up a fake auth server, but 99% of your code won&amp;#x27;t ever touch it, just the authentication tests. Tomorrow you add payments, you might want to put a boundary just before your &lt;i&gt;StripeRestAPI&lt;/i&gt; module to test the entire payment flow without contacting Stripe in your unit tests. Again, only the payment module tests ever need to touch Mox, the rest of your code doesn&amp;#x27;t. You place it before modules in the outer edge that have real-world side effects, not to isolate your functional and mostly pure core.&lt;p&gt;I recommend the DestroyAllSoftware talks, especially &lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;www.destroyallsoftware.com&amp;#x2F;talks&amp;#x2F;boundaries&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;www.destroyallsoftware.com&amp;#x2F;talks&amp;#x2F;boundaries&lt;/a&gt;&lt;p&gt;&amp;gt; And I just can’t justify it with “one day I might want to swap out the implementation”. YAGNI and if you do, deal with it then.&lt;p&gt;I agree with that. Using Mox to swap out implementations is a possible use case, but in practice it&amp;#x27;s better to hardcode things rather than trying to make it generic and swappable the first time around. Junior devs have a tendency to over-engineer code &amp;quot;because we might need to change it later.&amp;quot; My motto is &lt;i&gt;&amp;quot;copy and paste it three times before adding a layer of abstraction&amp;quot;&lt;/i&gt;</text></item><item><author>sarchertech</author><text>I hate Mox with a passion. Because I hate separating out the interface and implementation of something that is only ever going to have one real implementation.&lt;p&gt;The extra layer of indirection just for testing bugs me so much. And I just can’t justify it with  “one day I might want to swap out the implementation”. YAGNI and if you do, deal with it then.&lt;p&gt;So much legacy elixir code is an unreadable mess because of all the extra layers of interfaces that only get used for Mox. There’s nothing I dislike more than diving into an unfamiliar section of code and having to keep 15 files open to follow the logic for something that should have been in one module.</text></item><item><author>sph</author><text>Seconding the Mox recommendation, it&amp;#x27;s pretty good and enforces good separation of concerns in your application. It was created by José himself, so you know it&amp;#x27;s got a well-designed API. You just need to get used with using behaviours, and using the Application config to tell your code when to use the mock vs the real thing.&lt;p&gt;I use it to separate and test external API calls (i.e. to test the payment layer without making any request), to maintain separation between my code and an external library I might want to swap out at a later date, or even between various components of the application. Then writing unit tests becomes a breeze, and you don&amp;#x27;t need many integration tests.&lt;p&gt;&lt;a href=&quot;https:&amp;#x2F;&amp;#x2F;hexdocs.pm&amp;#x2F;mox&amp;#x2F;Mox.html&quot; rel=&quot;nofollow&quot;&gt;https:&amp;#x2F;&amp;#x2F;hexdocs.pm&amp;#x2F;mox&amp;#x2F;Mox.html&lt;/a&gt;</text></item><item><author>thibaut_barrere</author><text>Good write-up!&lt;p&gt;I will add:&lt;p&gt;- make sure to “stream” your transfers in general, instead of keeping whole file blobs in RAM. This to avoid refactoring at the least comfortable moment when a file gets too big in production&lt;p&gt;- it is quite easy to use Mox for isolated testing in general, and it works nicely with ExAws, so make sure to integrate those tests early on</text></item></parent_chain></comment><story><title>Fundamentals of Object Storage in Elixir</title><url>https://underjord.io/fundamentals-of-object-storage.html</url></story>