<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">First of all, José's approach also mocks globally in the Erlang context.  It might be different using local modules, but if you enter Erlang, then it's automatically global.<br></blockquote><div><br></div><div>The article uses a specific definition of the word "mock". So I agree with you that it is still a global mock but we are not mocking the system per the post definition (i.e. changing the implementation during tests). It is a nitpick, sorry, I just wanted to be precise.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
Would you consider, for that case, using instead:<br>
<br>
   -ifndef(twitter_api).<br>
   -define(twitter_api, default_twitter_api).<br>
   -endif.<br>
<br>
   show(Username) -><br>
       ?twitter_api:get_username(Username).<br>
<br>
Through build tools, you could define (here I'm using rebar3):<br>
<br>
   {profiles, [<br>
       [{test, [{erl_opts, [{d, twitter_api, test_twitter_api}]}]}]<br>
   ]}.<br></blockquote><div><br></div><div>This is a great solution. I will change the article to use a compile time version of the Elixir implementation as well. Although I would personally not worry about the cost behind accessing an ETS table, specially for this example where we are doing an HTTP request and parsing JSON response for every call, using something akin to a macro is just a better "default".</div><div> </div><div>> Q1: Am I going to need multiple modules there because it's a value I want to be configurable by users of a library at runtime?</div><div><br></div><div>The article was only about handling such cases in your application (no sharing). The thing is, if you want it to be configurable by users, then as you said the application environment is not enough. The good news is that once you provide your configuration mechanism, you have solved the testing problem as well.</div><div> </div><div>> Q2: Am I needing multiple modules to test alternating configurations?</div><div><br></div><div><div>Yup, I have replied that in another e-mail. It works to some extent as you can give different responses based on the argument. It depends on the system. There are simpler (like passing a closure or an argument) and more complex solutions as well, YMMV.</div></div><div><br></div><div>><span style="font-size:12.8px"> </span><span style="font-size:12.8px">I personally prefer to pay the cost of slightly longer test runs personally, than having my users pay the cost themselves at run time.</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">That's the only bit I actually disagree. It is not about the performance cost of the test but it is the conceptual cost of mocks. Specially in complex codebases where mocking often hides the fact the developers simply did not define a good contract between their dependencies. That was the main point of the article, anyway.  :)</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">Thanks Fred!</span></div></div><br></div></div>