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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Fl4m3Ph03n1x" data-post="11" data-topic="20418">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/fl4m3ph03n1x/48/11709_2.png" class="avatar"> Fl4m3Ph03n1x:</div>
<blockquote>
<p>Do you have any links or documentation to :counters.new ?<br>
I check the official erlang docs but was unable to find anything.</p>
</blockquote>
</aside>
<p>Well, probably the erlang docs:</p>
<aside class="onebox allowlistedgeneric" data-onebox-src="https://www.erlang.org/doc/apps/erts/counters.html">
  <header class="source">

      <a href="https://www.erlang.org/doc/apps/erts/counters.html" target="_blank" rel="noopener nofollow">erlang.org</a>
  </header>

  <article class="onebox-body">
    

<h3><a href="https://www.erlang.org/doc/apps/erts/counters.html" target="_blank" rel="noopener nofollow">counters — OTP 29.0.2 (erts 17.0.2)</a></h3>



  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>First hit on google for me <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" 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="117585" 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/test-function-was-called-exactly-x-times/20418/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-117585" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="117585"
                     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="117587" data-post-id="117587">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Fl4m3Ph03n1x" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Fl4m3Ph03n1x/120/11709_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Fl4m3Ph03n1x
                    <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="NobbZ" data-post="12" data-topic="20418">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/nobbz/48/27235_2.png" class="avatar"> NobbZ:</div>
<blockquote>
<p>Well, probably the erlang docs:</p>
</blockquote>
</aside>
<p>So this is not part of the ETS API, right?<br>
That explains why I coulnd’t find it, I was checking the ETS docs.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="117587" 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/test-function-was-called-exactly-x-times/20418/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-117587" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="117587"
                     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="117588" data-post-id="117588">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The module was <code>:counter</code>, not <code>:ets</code>.</p>
<p>Also <code>:counter</code> is part of the <code>:erts</code> application, while <code>:ets</code> is in <code>:stdlib</code>, which itself does depend on <code>:erts</code> IIRC. So <code>:counter</code> <strong>can not</strong> use <code>:ets</code>.</p>
<p>Also due to the constraints laid out in the module documentations prelude, I’d guess its using <code>:atomic</code>. Which again was mentioned already in this thread.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="117588" 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/test-function-was-called-exactly-x-times/20418/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-117588" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="117588"
                     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="117613" data-post-id="117613">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="hauleth" data-post="8" data-topic="20418">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/hauleth/48/18942_2.png" class="avatar"> hauleth:</div>
<blockquote>
<p>If you are using OTP 21+ then you can write it as:</p>
</blockquote>
</aside>
<p>Correct me if I’m wrong but I think the approach will only work if <code>MyApp.do_work(deps)</code> executes purely inside the test process - if there are any other processes spawned there could be a potential race condition:</p>
<p>There is no guarantee that by the time we hit <code>assert x == :counters.get(counter, 1)</code></p>
<ul>
<li>all of the the <code>x</code> calls have already completed</li>
<li>there won’t be any extraneous calls for a given time period.</li>
</ul>
<p><a class="mention" href="/u/lostkobrakai" rel="nofollow">@LostKobrakai</a>’s <code>assert_received</code>/<code>refuted_received</code> approach works for sequential and concurrent code within the given timeouts. So I would view the message based approach as more resilient and less aware of the implementation.</p>
<hr>
<blockquote>
<p>This is the basics of testing (usually you test if a function was called once) and couldn’t be farther from an implementation detail.</p>
</blockquote>
<p>Given the sparse details it’s kind of difficult to judge. You seem to be testing that a lookup was performed <code>X</code> times. Lookups can be cached, which could break the test.</p>
<p><a href="https://martinfowler.com/articles/mocksArentStubs.html" rel="noopener nofollow ugc">So should I be a classicist or a mockist?</a>:</p>
<blockquote>
<p>I really like the fact that while writing the test you focus on the <strong>result</strong> of the behavior, <em>not how it’s done</em>.</p>
</blockquote>
<p>From a classicist POV counting function invocations doesn’t seem to be focusing on the result (unless in some strange way it is).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="117613" 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/test-function-was-called-exactly-x-times/20418/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-117613" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="117613"
                     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="117615" data-post-id="117615">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yep, there is no such guarantee. But the same goes for all asynchronous tests, but <code>assert_received</code> and <code>refute_received</code> works on messages that already are there, so they have exactly the same problem, what you would need to use is <a href="https://hexdocs.pm/ex_unit/ExUnit.Assertions.html#assert_receive/3" rel="noopener nofollow ugc"><code>assert_receive</code></a> (yeah, this is confusing), but even then the problem will be there. In other words, in truly concurrent environment (like BEAM) being 100% sure that asynchronous requests will not be “magically” repeated is impossible, in NodeJS it is possible as there is no “true concurrency” as main loop is single threaded.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="117615" 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/test-function-was-called-exactly-x-times/20418/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-117615" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="117615"
                     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="117617" data-post-id="117617">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="hauleth" data-post="16" data-topic="20418">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/hauleth/48/18942_2.png" class="avatar"> hauleth:</div>
<blockquote>
<p>what you would need to use is <a href="https://hexdocs.pm/ex_unit/ExUnit.Assertions.html#assert_receive/3" rel="noopener nofollow ugc"> <code>assert_receive</code> </a> (yeah, this is confusing)</p>
</blockquote>
</aside>
<p>I had tunnel vision on <code>assert_receive</code> and <code>refute_receive</code> - even though I typed <code>assert_received</code> and <code>refute_received</code>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="117617" 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/test-function-was-called-exactly-x-times/20418/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-117617" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="117617"
                     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="117629" data-post-id="117629">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>You can skip all the mocks etc and just call the function and then use the trace features built into Erlang to ensure that it was called the correct number of times and with the correct params. Really so much easier</p>
<div class="youtube-onebox lazy-video-container" data-video-id="Cz8SCzoLZw4" data-video-title="Tracing is a super power in Elixir" data-video-start-time="" data-provider-name="youtube">
  <a href="https://www.youtube.com/watch?v=Cz8SCzoLZw4" target="_blank" class="video-thumbnail" rel="noopener nofollow ugc">
    <img class="youtube-thumbnail" src="https://img.youtube.com/vi/Cz8SCzoLZw4/maxresdefault.jpg" title="Tracing is a super power in Elixir" width="690" height="388">
  </a>
</div>
 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="117629" 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/test-function-was-called-exactly-x-times/20418/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-117629" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="117629"
                     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="117863" data-post-id="117863">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Just an observation.</p>
<p>I personally never got into mocking. I only crossed paths with it about 5 years ago when using Mocha/Sinon/Chai. Given the nature of JavaScript (or Ruby for that matter) I can see how one could go down that road.</p>
<p>My exposure to <a href="https://www.industriallogic.com/blog/history-microtests/" rel="noopener nofollow ugc">microtesting</a> goes back to the early days JUnit.</p>
<p>Mocking only became a thing some time later and when I looked into it in Java-land, a lot of it relied on reflection - my reaction:</p>
<ul>
<li><em>Eeewh!</em> That’s cheating.</li>
</ul>
<p>Well, not entirely. It’s justified if you are mocking 3rd party dependencies but even then there was always the choice to just decouple that behind a <a href="https://sourcemaking.com/design_patterns/facade" rel="noopener nofollow ugc">façade</a>.</p>
<blockquote>
<p>That’s cheating.</p>
</blockquote>
<p>That reaction was driven by the notion that mocking your own code removes the incentive to constantly assess and re-evaluate your <strong>boundaries</strong>. With classical testing there is the constant pressure to adjust your boundaries to be able to test what you want to test.</p>
<p>To me personally the primary benefit of <em>Test Driven Development</em> (in the classical sense) was that constant challenging of those boundaries (and the portals passing through them) - not the <em>test first</em> religion.</p>
<p>Of course even that can go off the rails as evidenced by the whole <a href="http://my-codeworks.com/blog/the-pain-of-dhh#block-yui_3_10_1_1_1399535785725_20833" rel="noopener nofollow ugc">test induced design damage</a> discussion.</p>
<p>One thing that isn’t clear from this discussion is:</p>
<ul>
<li>why is it so important that the lookup is called 10 times that it needs to be tested at this level?</li>
<li>what is responsible for performing that lookup in the real system?</li>
</ul>
<p>For example, if the lookup goes to another process anyway, wouldn’t it make more sense to test it with a fake process which keeps track of the invocation details that are then sent to the testing process?</p>
<hr>
<p>Somewhat related in the JavaScript space: <a href="https://youtu.be/x8sKpJwq6lY" rel="noopener nofollow ugc">Please don’t mock me</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="117863" data-batch-url="/posts/batch_likers">
                        4
                      </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/test-function-was-called-exactly-x-times/20418/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-117863" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="117863"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>