<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nicolas Trahan</title>
    <description>The latest articles on DEV Community by Nicolas Trahan (@nicolastrahan).</description>
    <link>https://dev.to/nicolastrahan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F167596%2Ff7a1e316-a4db-49bb-a227-759171b4b07b.jpg</url>
      <title>DEV Community: Nicolas Trahan</title>
      <link>https://dev.to/nicolastrahan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nicolastrahan"/>
    <language>en</language>
    <item>
      <title>The big idea from A Philosophy of Software Design</title>
      <dc:creator>Nicolas Trahan</dc:creator>
      <pubDate>Fri, 21 Apr 2023 18:46:50 +0000</pubDate>
      <link>https://dev.to/nicolastrahan/the-big-idea-from-a-philosophy-of-software-design-oge</link>
      <guid>https://dev.to/nicolastrahan/the-big-idea-from-a-philosophy-of-software-design-oge</guid>
      <description>&lt;p&gt;What makes a certain software design better than any other? In A Philosophy of Software Design, John Ousterhout offers a simple but profound idea: the goal of software design should be to minimize complexity as much as possible, with complexity being defined as “anything related to the structure of a software system that makes it hard to understand and modify the system”. It’s as simple as that! But why should this be our goal? As the author explains, as a system grows and complexity accumulates, “it becomes harder and harder for programmers to keep all of the relevant factors in their minds as they modify the system. This slows down development and leads to bugs, which slow development even more and add to its cost.”.&lt;/p&gt;

&lt;p&gt;I think this is extremely well put, and I love this definition of complexity because it’s entirely centered around human beings. I think it can be easy for engineers—but especially for managers!—to focus more on the objective aspects of the systems we work on: whether they work as specified, whether they’re performant, etc. But we can’t ignore this critical human idea of complexity, because if left unchecked, creeping complexity will gradually slow down the speed at which we can fix bugs and add features within any given system, correspondingly increasing developer frustration. Slower development time means greater costs, and increased frustration means higher developer turnover, so minimizing complexity should be something everyone at our organizations, from developers all the way to CEOs, should be concerned with.&lt;/p&gt;

&lt;p&gt;The author builds on this simple definition of complexity to define the complexity of an overall system as the sum of the complexities of each part, weighed by the fraction of time that developers spend working on that part. At first glance it didn’t seem to me like that definition was an accurate representation of what most developers actually mean when they say that a system is complex. But on further thought, we wouldn’t for instance consider an otherwise simple system that makes use of a modern relational database as “complex”. Yes, the database system itself is extremely complex, but since we don’t need to peek inside and contemplate its inner workings in order to make use of it, its complexity has essentially been &lt;a href="https://grugbrain.dev/#grug-on-factring-your-code"&gt;trapped&lt;/a&gt;; therefore the overall system certainly feels simple. So on further thought, I think this definition is actually brilliant, and an incredibly useful way of thinking about the complexity of a system and the quality of its design. Reduce this measure for a given system and it will become easier, more pleasant, and more efficient to maintain.&lt;/p&gt;

&lt;p&gt;With this powerful definition of complexity in hand, the rest of the book looks at various ways that complexity can creep into our software systems and offers specific tips on how to fight these various manifestations. I think my single favorite one of these might be the idea of deep versus shallow modules: deep modules hide a lot of functionality behind a relatively small interface, and shallow modules are the opposite. The author explains that “Module depth is a way of thinking about cost versus benefit. The benefit provided by a module is its functionality. The cost of a module (in terms of system complexity) is its interface.” I never thought of interfaces as adding complexity to our systems, but of course it’s obviously true: interfaces need to be studied to be understood and made useful, just like any other parts of our systems. And what this means overall is that deep modules should be preferred over shallow ones. In some cases, the cost of a module, its interface, might even be outweighed by its benefit, the complexity it hides, meaning it probably shouldn’t exist at all! It also means that we shouldn’t feel compelled to automatically start slicing up longer functions or modules into smaller pieces just because of their length. If they’re long but still feel rather easy to understand, we might make them overall &lt;em&gt;more&lt;/em&gt; complex by slicing them up, since every new piece now comes with the burden of an interface that adds complexity to the overall product.&lt;/p&gt;

&lt;p&gt;Here’s a nice little chart from the book that illustrates this idea of deep versus shallow modules:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dkaL_BVe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/obg9f51i1sp2df5q06mf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dkaL_BVe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/obg9f51i1sp2df5q06mf.png" alt="Deep versus shallow modules chart" width="762" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There’s a lot of other great ideas and tips to reduce complexity discussed throughout the book, for instance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chapter 3 discusses the difficult problem of knowing when you should be focusing on design work (”strategic programming”) versus when you should be focusing on just getting something to work (”tactical programming”). I love and wholeheartedly agree with the following quote from this chapter: “the ideal design tends to emerge in bits and pieces, as you get experience with the system. Thus the best approach is to make lots of small investments on a continual basis”.&lt;/li&gt;
&lt;li&gt;Chapter 5 argues that the most important technique to achieve deep modules is “information hiding”, which is knowledge that is “embedded in the module’s implementation but does not appear in its interface, so it is not visible to other modules”. The part about information not being visible to other modules is critical, because if the information isn’t hidden, the complexity hasn’t actually been trapped. This can manifest itself in what the author calls “information leakage”, where information within a module is actually duplicated outside of it, contributing to complexity. I think these ideas of trying to hide as much information as possible within our modules and of preventing information leakage are highly useful to keep in mind while designing software.&lt;/li&gt;
&lt;li&gt;Chapter 11 promotes the interesting idea of considering multiple designs for each major decision: “you’ll end up with a much better result if you consider multiple options for each major design decision”. It’s not something I have the habit of doing, but I can see how it would help produce better designs: I’ll have to give it a try!&lt;/li&gt;
&lt;li&gt;I love Chapter 12 because it provides a rebuttal to common excuses for not writing comments, excuses that I’ve heard myself many times before. I agree with the author that comments can make systems much easier to understand and therefore maintain, and that they’re worth investing in.&lt;/li&gt;
&lt;li&gt;The title of Chapter 13 itself is a simple yet powerful idea we should always keep in mind when writing comments: “comments should describe things that aren’t obvious from the code”.&lt;/li&gt;
&lt;li&gt;Chapter 14 is interesting because it discusses the critical problem of choosing names for identifiers! Of course choosing names is an important aspect of reducing complexity, since good names can obviously make our systems easier to understand. But unfortunately it’s notoriously hard to do, as the famous quote attributed to Phil Karlton says: “There are only two hard things in Computer Science: cache invalidation and naming things". So it’s nice to have a chapter dedicated to this topic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a few pieces of advice in the book I didn’t necessarily agree with though. For instance, in Chapter 15 the author recommends that you write your comments at the beginning of the design process, before writing any code. I just can’t see myself following this advice. It reminds me of test-driven development, where developers are encouraged to write tests before any implementation code, which I also don’t think is practical or useful most of the time. I think writing a good description of a design is a difficult and time consuming activity, and in practice as developers we need to actually write some code and experiment with our design ideas to see if they even work. In other words, our designs should probably evolve quite a bit before we settle on something we’re willing to commit to (this idea of experimenting with multiple design options is even recommended in the book itself, in Chapter 11, as I mentioned earlier). I think it would be quite inefficient if we had to write and evolve our comments every time we changed our design in the early experimental phases: better, in my opinion, to wait until things have settled down a bit.&lt;/p&gt;

&lt;p&gt;Apart from that, I think the book would benefit from a broader discussion on automated testing and how it might affect the design process. It does devote a chapter to the tension between performance and complexity, yet a similar tension clearly exists between testability and complexity. Considering how important automated testing is to modern software development, a chapter on the topic would be useful.&lt;/p&gt;

&lt;p&gt;Overall, A Philosophy of Software Design offers a powerful mental model and a North Star for guiding our software design decisions. I highly recommend it to software developers at any level of experience.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>programming</category>
    </item>
    <item>
      <title>Fast feedback loops in software developement: they matter!</title>
      <dc:creator>Nicolas Trahan</dc:creator>
      <pubDate>Tue, 26 Oct 2021 03:29:31 +0000</pubDate>
      <link>https://dev.to/nicolastrahan/fast-feedback-loops-in-software-developement-they-matter-2haj</link>
      <guid>https://dev.to/nicolastrahan/fast-feedback-loops-in-software-developement-they-matter-2haj</guid>
      <description>&lt;p&gt;There’s been some drama as of late with regards to Microsoft’s decision to remove the hot reloading capability from .NET command line tools for the upcoming .NET 6 release.&lt;/p&gt;

&lt;p&gt;For those who don’t know, .NET is a Microsoft-led open-source and cross-platform software framework that supports a variety of languages, most notably C#, and a variety of application types, such as web applications/services, command line tools, and desktop and mobile applications. The feature in question, .NET Hot Reload, allows developers to apply code changes to applications they’re debugging without having to restart them. It’s similar to React Fast Refresh or Hot reload in Flutter.&lt;/p&gt;

&lt;p&gt;So what happened exactly? On October 20th, Microsoft &lt;a href="https://devblogs.microsoft.com/dotnet/update-on-net-hot-reload-progress-and-visual-studio-2022-highlights/"&gt;announced&lt;/a&gt; that hot reloading would only be available through Visual Studio for Windows in the upcoming November 8th general availability release of .NET 6. This means that developers using command line tools to develop for .NET—those using Visual Studio Code on any platform, for instance—wouldn’t be able to benefit from hot reloading once they switched to the GA release. This announcement was especially surprising and frustrating since this feature had been available in preview for a while, seemed to be working decently well, and was pulled so close to the release date.&lt;/p&gt;

&lt;p&gt;The backlash was strong and immediate: see the coverage by &lt;a href="https://www.theverge.com/2021/10/22/22740701/microsoft-dotnet-hot-reload-removal-decision-open-source"&gt;The Verge&lt;/a&gt; or &lt;a href="https://dusted.codes/can-we-trust-microsoft-with-open-source"&gt;by Dustin Moris Gorski, a .NET developer&lt;/a&gt;, for instance. Thankfully though, Microsoft listened to the .NET open-source community and soon &lt;a href="https://devblogs.microsoft.com/dotnet/net-hot-reload-support-via-cli/"&gt;reversed course&lt;/a&gt;, deciding to allow the feature to be included in the final release after all. (also see this &lt;a href="https://www.theverge.com/2021/10/23/22742282/microsoft-dotnet-hot-reload-u-turn-response"&gt;article by The Verge&lt;/a&gt; for more details on the reversal)&lt;/p&gt;

&lt;p&gt;Why were .NET devs so vocal and angry about Microsoft’s decision? Clearly, Microsoft handled the situation very poorly, but no doubt the frustration was amplified because of how powerful and important this feature is.&lt;/p&gt;

&lt;p&gt;I can relate. In my current project at work, I’m working on an ASP.NET Core MVC application with an HTML/CSS/Javascript frontend, using Visual Studio on Windows as my IDE. With this setup, whenever I'm debugging the application and I edit any file that isn’t a view, the entire application needs to be stopped and restarted before I can see my changes in action. This takes a little while, but even then I'm still not done! Now I'm staring at the first page of my site and all the inputs are blank, so now I have to navigate back to where I was before and enter all my data back into the page again.&lt;/p&gt;

&lt;p&gt;But the impact on my productivity goes beyond the time that's wasted getting back to the previous state in my application every time I make some code changes. It’s also the fact that the whole process is distracting and might take me out of my flow. By the time I'm finally back to where I was before, I have to ask myself, “What was I trying to do again?”. Sometimes I can’t remember! I need to get refocused, a huge waste of mental energy. Being able to simply save my source code and see the changes applied instantly would allow me to keep my focus and preserve my limited supply of mental energy, allowing me to be much more productive.&lt;/p&gt;

&lt;p&gt;In general, hot reloading can be seen as a tool to speed up what some people call the “inner loop”, the “inner dev loop”, or the “launch/debug/update loop”, which is the process you go through repeatedly in development of making code changes and seeing/testing the resulting application. So what’s the moral of this story? Having a fast inner loop can greatly boost your productivity as a developer. Which by the way is something you might have realized if you've ever worked in a dynamic language like Javascript, PHP, Python or Ruby. And in my opinion, I'd actually say that their ability to provide fast inner loops have always been one of the main, if not &lt;em&gt;the&lt;/em&gt; main selling points of dynamic languages. But I digress… happy coding and get that fast inner loop if you can!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/photos/u2d0BPZFXOY"&gt;Tine Ivanič on Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>coding</category>
    </item>
    <item>
      <title>A React multi-step form</title>
      <dc:creator>Nicolas Trahan</dc:creator>
      <pubDate>Wed, 02 Jun 2021 22:15:06 +0000</pubDate>
      <link>https://dev.to/nicolastrahan/react-multi-step-form-910</link>
      <guid>https://dev.to/nicolastrahan/react-multi-step-form-910</guid>
      <description>&lt;p&gt;There's a ton of HTML multi-step form examples out there: see &lt;a href="https://csshint.com/multi-step-html-forms/"&gt;https://csshint.com/multi-step-html-forms/&lt;/a&gt; for instance. So why create another one? Simply put, I couldn't find a form that satisfied my two main requirements:&lt;/p&gt;

&lt;p&gt;1) Responsive. The form should look good on a phone, a desktop, and everything in between. It's 2021 and most web traffic now goes  through mobile devices, so making your pages responsive should be a top priority.&lt;br&gt;
2) It should be easy to change the number of steps, and the form should look good and stay responsive regardless of how many steps you have.&lt;/p&gt;

&lt;p&gt;I was also looking for the following:&lt;br&gt;
3) You choose be able to choose an icon to represent each step.&lt;br&gt;
4) Clicking on a step indicator should navigate to that step.&lt;/p&gt;

&lt;p&gt;Here's what I came up with:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/multi-step-form-uyy5l"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The labels will disappear when there isn't enough horizontal space for them, but the form isn't smart enough to figure out the perfect breakpoint on its own: you'll have to manually specify that value in multi-step-nav.css. &lt;/p&gt;

&lt;p&gt;Why add next and previous buttons in each step instead of reusing the same buttons everywhere? Doing it like this actually helps with the tabbing behavior: if you've tabbed to a next/previous button and press Enter, tabbing again will move you to the top of the new section, instead of tabbing out of the form towards the bottom of the document.&lt;/p&gt;

&lt;p&gt;There's one accessibility feature I couldn't seem to figure out, however. When using NVDA (the most popular desktop screen reader according to the latest &lt;a href="https://webaim.org/projects/screenreadersurvey8/"&gt;WebAIM survey&lt;/a&gt;) in browse mode, using the down arrow after pressing the Next or Previous button won't start reading at the top of the newly selected section. Anyone out there know how to fix this? 🙂&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/photos/tQQ4BwN_UFs"&gt;Kelly Sikkema on Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>react</category>
      <category>html</category>
      <category>typescript</category>
    </item>
    <item>
      <title>No, don't mock the Redux store!</title>
      <dc:creator>Nicolas Trahan</dc:creator>
      <pubDate>Sun, 03 Jan 2021 20:31:33 +0000</pubDate>
      <link>https://dev.to/nicolastrahan/no-don-t-mock-the-redux-store-1fih</link>
      <guid>https://dev.to/nicolastrahan/no-don-t-mock-the-redux-store-1fih</guid>
      <description>&lt;p&gt;As a side project, I’m currently working on a Chrome extension built using Create React App, Typescript, and the Redux Toolkit. For testing, I’m using Jest (set up for me by Create React App) and React Testing Library. Recently, I ran into a weird problem with my test suite: an assertion that a certain function was being called was failing, even though I knew for a fact that it was, indeed, being called. Here’s the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proceduresAsAny&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;procedures&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Add bookmark inside works&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createBookmarkNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;procedures&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createBookmarkNode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;createBookmarkNodeMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nx"&gt;proceduresAsAny&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createBookmarkNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createBookmarkNodeMock&lt;/span&gt;

    &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByTestId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;folder-menu-add-bookmark-inside&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createBookmarkNodeMock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toHaveBeenCalledTimes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;expectedArgs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bookmarks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BookmarkCreateArg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;parentId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;New Bookmark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://google.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createBookmarkNodeMock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;anything&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="nx"&gt;expectedArgs&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;proceduresAsAny&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createBookmarkNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createBookmarkNode&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How did I know the mock function was actually being called? Simple, by giving it an implementation that would log to the console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;createBookmarkNodeMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;calling createBookmarkNodeMock!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the Jest console was indeed printing "calling createBookmarkNodeMock!". So what gives? Why was the assertion failing?&lt;/p&gt;

&lt;p&gt;Turns out the issue was async-related. Indeed, the button’s click event handler wasn’t just changing a component’s state or dispatching a simple Redux event, it was dispatching an async thunk that contained an await, meaning that everything that followed the await in the body of the thunk would be run after my test function finished running. Not too useful when I’m trying to test the effects of that button click!&lt;/p&gt;

&lt;p&gt;So what’s the solution? All the advice I was finding online was saying the same thing: mock the store! Even the official Redux docs were saying that (see &lt;a href="https://redux.js.org/recipes/writing-tests#async-action-creators"&gt;https://redux.js.org/recipes/writing-tests#async-action-creators&lt;/a&gt;). Now that’s cool and all, but there’s just one problem with that: I don’t want to mock the store! I’m trying to write a test that shows that my function is being called in a specific way when a certain button is pressed. I don’t care if that’s being done by sending a certain event to the store. In fact, I don’t even care if Redux is used at all! As long as my function ends up being called, I’m happy. So how can I write such a test?&lt;/p&gt;

&lt;p&gt;The solution I found was pretty simple: React Testing Library’s waitFor function. waitFor will repeatedly call the given function until it doesn’t throw an error. So all I needed to do to get my test working was to replace this line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createBookmarkNodeMock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toHaveBeenCalledTimes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waitFor&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createBookmarkNodeMock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toHaveBeenCalledTimes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is there a better way of accomplishing this without using waitFor? Do you disagree and think I should actually mock the store? Let me know in the comments!&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus: why is my mock OK?
&lt;/h3&gt;

&lt;p&gt;In not wanting to mock the Redux store here, I’m certainly not saying that all mocks are bad. In the test shown earlier, for instance, I’m mocking a function that calls the Chrome API to create a bookmark node. I don’t want to actually call this function in my tests because 1) Setting up an environment where I can call this real API is complicated, 2) I’m very confident that the feature I’m testing is implemented correctly if the system actually calls the mocked function in the way that the test describes, and 3) I expect a test using the real Chrome API to be slower than the one using a mock. For these reasons, I’m happy to mock out the createBookmarkNode function (and in fact, I created this function specifically because I wanted to mock it out).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/photos/eBE3pEIZjbc?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditShareLink"&gt;Wei Pan on Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>redux</category>
      <category>testing</category>
      <category>jest</category>
      <category>react</category>
    </item>
  </channel>
</rss>
