<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="362277" data-post-id="362277">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Linuus" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Linuus/120/1104_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Linuus
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="gaggle" data-post="16" data-topic="70404">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gaggle/48/30793_2.png" class="avatar"> gaggle:</div>
<blockquote>
<p>The “only ever mock 3rd-party code” rule lacks nuance. Over-mocking is bad - but under-mocking is <strong>also</strong> a problem.</p>
</blockquote>
</aside>
<p>That’s not what <em>I</em> said though <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> I said I <em>try</em> to keep mocks for calls to 3rd party API’s. What I meant here is 3rd party systems that I have no control over or are annoying to test against (slow, async conflicts, can’t run locally…). I’ve seen code that tries to juggle globally configured Mox mocks for all kinds of dependencies, both purely functional internal code as well as external. And if you need to write behaviours etc for all that just for tests, it gets messy real fast and you have no idea what code is actually running during your tests.</p>
<p>Also, this is in no way a strict rule. Sometimes I inject a simple function if it makes sense (usually at some boundary) or a mock, but <em>first</em> I want to try and isolate side-effects as I showed above. Functional dependencies are not that bad when testing.</p>
<p>This screenshot is from the <a href="https://pragprog.com/titles/lmelixir/testing-elixir/" rel="noopener nofollow ugc">Elixir testing book</a> (I hope it’s ok that I share it)</p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/8/b/8b16c05ce0e8f65ad7cbba4a5f0f11e4fe6a88c3.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/8b16c05ce0e8f65ad7cbba4a5f0f11e4fe6a88c3" title="testing" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/3X/8/b/8b16c05ce0e8f65ad7cbba4a5f0f11e4fe6a88c3_2_528x600.jpeg" alt="testing" data-base62-sha1="jQr70FTb2FjhyPozNTe9jLLFSsr" width="528" height="600" srcset="https://forum.elixirforum.com/uploads/default/optimized/3X/8/b/8b16c05ce0e8f65ad7cbba4a5f0f11e4fe6a88c3_2_528x600.jpeg, https://forum.elixirforum.com/uploads/default/optimized/3X/8/b/8b16c05ce0e8f65ad7cbba4a5f0f11e4fe6a88c3_2_792x900.jpeg 1.5x, https://forum.elixirforum.com/uploads/default/optimized/3X/8/b/8b16c05ce0e8f65ad7cbba4a5f0f11e4fe6a88c3_2_1056x1200.jpeg 2x" data-dominant-color="E4ECE9"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">testing</span><span class="informations">1200×1362 75.5 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<p>And, of course there are exceptions and tradeoffs as always. <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> But my main point is that I think the default reaction should not be to reach for and inject mocks all over the place.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="362277" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/automating-tests-in-elixir-projects/70404/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-362277" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="362277"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #17"></div>
  </section>
</div>
    <div class="postbit" id="362275" data-post-id="362275">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="gaggle" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gaggle/120/30793_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  gaggle
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="dimitarvp" data-post="15" data-topic="70404">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/48/38664_2.png" class="avatar"> dimitarvp:</div>
<blockquote>
<p>If you have to mock code that is under your control then you’re taking the easy way out now that will introduce more work in the (likely very near) future.</p>
</blockquote>
</aside>
<p>I like this point, especially in how it frames the issue in terms of <strong>time</strong>. Test doubles can be a temporary measure - used while waiting for a better design to emerge. Or one might deliberately refactor <em>toward</em> test doubles, deciding they’re simpler than wrestling with domain-heavy test setups.</p>
<p>I think I’m putting words in your mouth though - we likely disagree on when test doubles are appropriate - but I appreciate the idea that test strategy is part of the evolving design, not separate from it.</p>
<aside class="quote no-group" data-username="dimitarvp" data-post="15" data-topic="70404">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/48/38664_2.png" class="avatar"> dimitarvp:</div>
<blockquote>
<p>There are no “camps” here. I strongly object to them existing. It’s simply choosing your poison / tradeoffs. That’s not a “camp”.</p>
</blockquote>
</aside>
<p>That’s a helpful clarification, thank you. I don’t associate “camp” at all with your reaction, but I see your point. “Tradeoffs” works for me <img src="https://forum.elixirforum.com/images/emoji/apple/+1.png?v=15" title=":+1:" class="emoji" alt=":+1:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="362275" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/automating-tests-in-elixir-projects/70404/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-362275" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="362275"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="362273" data-post-id="362273">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="gaggle" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gaggle/120/30793_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  gaggle
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I like a lot of the thinking here - and <a class="mention" href="/u/linuus" rel="nofollow">@Linuus</a>, your focus on isolating side effects to avoid excessive mocking is spot on. I’d just add that the top-level orchestrator in your solution is itself part of the broader conversation around dependency injection and test doubles, which is what my blog tries to unpack.</p>
<p>Here’s a variant of your setup to illustrate where I’m coming from:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Warehouse do
  def empty?(%Warehouse{inventories: inventories}) do
    inventories
    |&gt; Enum.map(&amp;Inventory.all_products/1)
    |&gt; List.flatten()
    |&gt; Enum.empty?()
  end
end
</code></pre>
<p>In this version, both <code>Warehouse</code> and <code>Inventory</code> are complex internal domains (backed by DBs and external systems), and under our control. The idea is that querying a warehouse <strong>necessarily</strong> means querying is inventories. This mirrors your example, but focuses on two internal systems.</p>
<p>We could decouple this with an orchestrator (e.g. <code>WarehouseQuerier</code>, like your <code>MessageProcessor</code>), but as long as the systems depend on each other, the conversation around dependency injection becomes relevant. And if we stick to <strong>only</strong> mocking external systems, testing this orchestrator would mean mocking the DB and APIs behind both <code>Warehouse</code> and <code>Inventory</code>.</p>
<p>That can bring real cost in the form of:</p>
<ul>
<li>a lot of setup, most of which is already handled in the domain’s own tests so it would duplicate those efforts.</li>
<li>It demands domain knowledge of both systems just to test their integration.</li>
</ul>
<p>At some point along that spectrum, I’m happy to discuss the tradeoff of using simple, high-fidelity test doubles for internal systems, if it makes the tests clearer and easier to work with.</p>
<p>The idea of strictly banning test doubles except at fully external boundaries can just as well introduce new complexities. Two points in particular:</p>
<ul>
<li>The “only ever mock 3rd-party code” rule lacks nuance. Over-mocking is bad - but under-mocking is <strong>also</strong> a problem.</li>
<li>It assumes developers can always manage deep cross-domain integrations in tests, and I’ve met developers who are so smart they can’t see that. They don’t see the signs of other developers struggling. It is a great kindness to accept a little mocking if it goes a long way to reduce the cognitive burden.</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="362273" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/automating-tests-in-elixir-projects/70404/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-362273" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="362273"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="362223" data-post-id="362223">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dimitarvp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/120/38664_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dimitarvp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="gaggle" data-post="10" data-topic="70404">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gaggle/48/30793_2.png" class="avatar"> gaggle:</div>
<blockquote>
<p>test doubles are invaluable in testing, including internally. They help isolate systems and keep tests focused.</p>
</blockquote>
</aside>
<p>Which is much better achieved by reducing the size of monster functions or modules.</p>
<p>Mocking should be used only for super complex external systems your app depends on. Mocking those helps you ascertain with <em>some</em> degree of certainty (far from 100%) that your code acts adequately to what the external system is doing.</p>
<p>If you have to mock code that is under your control then you’re taking the easy way out now that will introduce more work in the (likely very near) future.</p>
<p>Also known as tech debt.</p>
<p>There are no “camps” here. I strongly object to them existing. It’s simply choosing your poison / tradeoffs. That’s not a “camp”.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="362223" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/automating-tests-in-elixir-projects/70404/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-362223" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="362223"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="362210" data-post-id="362210">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Linuus" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Linuus/120/1104_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Linuus
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Right, yeah that is a great talk <img src="https://forum.elixirforum.com/images/emoji/apple/+1.png?v=15" title=":+1:" class="emoji" alt=":+1:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="362210" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/automating-tests-in-elixir-projects/70404/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-362210" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="362210"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="362194" data-post-id="362194">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="LostKobrakai" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/LostKobrakai/120/3072_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  LostKobrakai
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Linuus" data-post="12" data-topic="70404">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/linuus/48/1104_2.png" class="avatar"> Linuus:</div>
<blockquote>
<p>I feel like approaches like this helps a lot with dealing with (not) mocking etc. But, I don’t have that much experience with bigger Elixir projects yet though so we’ll see.</p>
</blockquote>
</aside>
<p>That approach is also what is presented in this great talk: <a href="https://www.destroyallsoftware.com/talks/boundaries" class="inline-onebox" rel="nofollow">Boundaries</a></p>
<p>I personally like this approach quite a lot.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="362194" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/automating-tests-in-elixir-projects/70404/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-362194" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="362194"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="362191" data-post-id="362191">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Linuus" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Linuus/120/1104_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Linuus
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>This is an interesting topic and something I’ve tried to figure out myself lately as I’m working on an Elixir project at work.<br>
I really dislike mocking too much, and try to keep that for 3rd party APIs that are almost always mocked.</p>
<p>What I’ve seen though is when you have long call chains with side-effects in the end. Then it becomes annoying as it makes all functions “impure”.</p>
<p>Say you have this (never mind any error handling):</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule MessageProcessor do
  def process(message) do
    message
    |&gt; Parser.parse()
    |&gt; MessageHandler.handle()
  end
end

defmodule MessageHandler do
  def handle(message) do
    case verify_message(message) do
      :ok -&gt; Router.route(message)
      {:error, reason} -&gt; {:error, reason}
    end
  end
end

defmodule Router do
  def route(%FooMessage{} = message) do
    ExternalAPI.call(message)
  end

  def route(%BarMessage{} = message) do
    AnotherExternalAPI.call(message)
  end
end
</code></pre>
<p>If you test the Router module it’s quite straight forward. You can update it to inject the external API module, or set a mock globaly using Mox.</p>
<p>But, then when you want to test the MessageHandler and MessageProcessor - they also end up calling the 3rd party.<br>
So for MessageProcessor for example, your alternatives are:</p>
<ol>
<li>Write a behaviour for the MessageHandler module and inject a mock. Don’t like mocking internal modules…</li>
<li>If the 3rd party API mocks are set globally, you need to add <code>expect(...)</code> calls in the MessageProcessor tests. Not sure if that makes sense. You’d do the same for MessageHandler tests…</li>
<li>If the 3rd party API mocks are not set globally, you need to inject them all the way from MessageProcessor → MessageHandler → Router. Horrible <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></li>
<li>Rewrite the code.</li>
</ol>
<p>Lately I’ve been leaning more to 4 when I see code like this, trying to isolate the side effects.<br>
Something like this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule MessageProcessor do
  def process(message) do
    with {:ok, parsed_message} &lt;- Parser.parse(message),
      {:ok, verified_message} &lt;- MessageVerifyer.verify(parsed_message),
      {:ok, {module, fun, args} &lt;- Router.route(verified_message) do
        apply(module, fun, args)
      end
  end
end

defmodule MessageVerifyer do
  def verify(message) do
    if good?(message) do
      {:ok, message}
    else
      {:error, :bad_message}
    end
  end
end

defmodule Router do
  def route(%FooMessage{} = message) do
    {ExternalApi, :call [message]}
  end

  def route(%BarMessage{} = message) do
    {AnotherExternalApi, :call [message]}
  end
end
</code></pre>
<p>Now the MessageVerifyer and Router have no side-effects and can easily be tested. The MessageProcessor would not be “unit tested” but only integration tested (or whatever you want to call it), and I would mock the 3rd party API calls with either a global Mox mock or using Bypass or something. Since the MessageProcessor basically only “integrates” different parts of your codebase, a “unit test” doesn’t make much sense.</p>
<p>I feel like approaches like this helps a lot with dealing with (not) mocking etc. But, I don’t have that much experience with bigger Elixir projects yet though so we’ll see.</p>
<p>What do you think about that?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="362191" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/automating-tests-in-elixir-projects/70404/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-362191" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="362191"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="362160" data-post-id="362160">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Schultzer" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Schultzer/120/4339_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Schultzer
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I think we’re talking past each other, again terms are being conflated, if not made more complex.</p>
<p>When I’m talking about mocking internal code, then what typically happens is that the mock changes your code. If you need to modify your business logic in a perverse goal of test isolation to the extreme. Then you fundamentally have bigger problem at hand, which is basically experience. It takes a long time for any new developer to learn how to cut through the pedantic BS, especially when it comes to testing which is some of the most opinionated discussions you can have.</p>
<p>Regardless my point being a more fundamental software engineering 101. Everything we do is data transformations. input → output.</p>
<p>We don’t need to make it more complex. When we understand this, then we can build beautiful simple systems, which can grow into complex systems that are easier to understand.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="362160" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/automating-tests-in-elixir-projects/70404/11">Post #10</a>
	                </div>
	            </div>
              <div id="likers-container-362160" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="362160"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #10"></div>
  </section>
</div>
    <div class="postbit" id="362159" data-post-id="362159">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="gaggle" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gaggle/120/30793_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  gaggle
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I think quite the contrary: test doubles are invaluable in testing, including internally. They help isolate systems and keep tests focused. I used the word “mock” earlier, but didn’t mean to imply a specific kind of test double — any chance that caused some misunderstanding?</p>
<p>Internal test doubles let us test specific behavior without pulling in all underlying dependencies. Dismissing them overlooks how they can simplify complex systems and prevent growing dependency chains. Not every project needs them — but when used well, they help many devs better understand system boundaries.</p>
<p>This isn’t to my knowledge a controversial position in the wider testing world. <em>Mockist vs. classicist</em> doesn’t capture all the nuance we’re touching on here, but it hints at the broad and diverse approaches under the test automation umbrella. For better or worse, we’ve got to learn to see eye to eye <img src="https://forum.elixirforum.com/images/emoji/apple/joy.png?v=15" title=":joy:" class="emoji" alt=":joy:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="362159" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/automating-tests-in-elixir-projects/70404/10">Post #9</a>
	                </div>
	            </div>
              <div id="likers-container-362159" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="362159"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #9"></div>
  </section>
</div>
    <div class="postbit" id="362155" data-post-id="362155">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Schultzer" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Schultzer/120/4339_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Schultzer
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Mocking internal code is a huge red flag, it tells everyone that there is fundamental architectural problem, or lack of experience.</p>
<p>In the end, programming is all about data transformations. To put it simple: input → output</p>
<p>So when we test, then we want to assert that we got the expected output from the input.</p>
<p>With that in mind we can design our system in such a way that we only care about changing the input, that input can come from a lot of places.</p>
<p>I saw you mention unit testing and E2E. People tend to conflate all these terms. 99% of the time programmers write integration test, E2E test is a subset of integration test. All your Ecto test are integration test. If a function has side effects then the only way to test it is by an integration test.</p>
<p>Unit test requires a function without side effects.</p>
<p>Regardless of this pedantickery lets just agree that tests should be simple to reason about and if you feel that mocking is the right answer, then you properly have a bigger problem at hand.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="362155" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/automating-tests-in-elixir-projects/70404/9">Post #8</a>
	                </div>
	            </div>
              <div id="likers-container-362155" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="362155"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #8"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/70404/load_more?page=3">Load more posts (7 remaining)</a>
</div></template></turbo-stream>