<?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: Axmin Shrestha</title>
    <description>The latest articles on DEV Community by Axmin Shrestha (@axsh).</description>
    <link>https://dev.to/axsh</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%2F471666%2Ff580b0e5-8a24-4819-a10e-b234dcb4f079.png</url>
      <title>DEV Community: Axmin Shrestha</title>
      <link>https://dev.to/axsh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/axsh"/>
    <language>en</language>
    <item>
      <title>Mock vs. SpyOn in Vitest with TypeScript: A Guide for Unit and Integration Tests</title>
      <dc:creator>Axmin Shrestha</dc:creator>
      <pubDate>Sun, 26 Jan 2025 23:56:50 +0000</pubDate>
      <link>https://dev.to/axsh/mock-vs-spyon-in-vitest-with-typescript-a-guide-for-unit-and-integration-tests-2ge6</link>
      <guid>https://dev.to/axsh/mock-vs-spyon-in-vitest-with-typescript-a-guide-for-unit-and-integration-tests-2ge6</guid>
      <description>&lt;h2&gt;
  
  
  When to mock dependencies and when to spy on behavior for effective testing. 
&lt;/h2&gt;

&lt;p&gt;Testing is the backbone of reliable software, but choosing the right tools for the job can be tricky. In &lt;strong&gt;Vitest&lt;/strong&gt; with TypeScript, two powerful utilities, &lt;code&gt;mock&lt;/code&gt; and &lt;code&gt;spyOn&lt;/code&gt;, often cause confusion. Let’s break down their use cases, differences, and best practices to help you write better unit and integration tests.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;What’s the Difference?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;At a glance:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;mock&lt;/code&gt;&lt;/strong&gt; replaces a function/module’s implementation entirely.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;spyOn&lt;/code&gt;&lt;/strong&gt; observes a function’s behavior without changing it (unless you tell it to).
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;When to Use &lt;code&gt;mock&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;vi.mock&lt;/code&gt; to &lt;strong&gt;isolate your code from external dependencies&lt;/strong&gt; by replacing their implementations.  &lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Use Cases&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Unit Testing&lt;/strong&gt;
Mock dependencies (e.g., APIs, databases) to test a single component in isolation.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="c1"&gt;// Mock an API client&lt;/span&gt;
   &lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/services/api&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;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
     &lt;span class="na"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;mockResolvedValue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fake&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;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;displays mocked data&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="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DataFetcher&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&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="nf"&gt;expect&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="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fake&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&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;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid Side Effects&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Prevent network calls, file system operations, or other costly actions.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simulate Edge Cases&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Force errors or unusual responses (e.g., 500 status codes).  &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;When to Use &lt;code&gt;spyOn&lt;/code&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;vi.spyOn&lt;/code&gt; to &lt;strong&gt;track function calls and arguments&lt;/strong&gt; while preserving the original behavior.  &lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Use Cases&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Integration Testing&lt;/strong&gt;
Verify interactions between modules without breaking their real behavior.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;analytics&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/utils/analytics&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;logs an event on button click&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;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;trackSpy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;analytics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;trackEvent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SignupButton&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="nx"&gt;userEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&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="nf"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sign Up&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
     &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trackSpy&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalledWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;signup_clicked&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;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Assert Function Behavior&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Check if a function was called, how many times, or with specific arguments.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Temporary Overrides&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Mock a function for a single test, then restore it:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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;spy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;isValid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mockReturnValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="c1"&gt;// Test invalid case&lt;/span&gt;
   &lt;span class="nx"&gt;spy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mockRestore&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Restore original&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Unit Tests vs. Integration Tests&lt;/strong&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test Type&lt;/th&gt;
&lt;th&gt;Mock (&lt;code&gt;vi.mock&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;Spy (&lt;code&gt;vi.spyOn&lt;/code&gt;)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Unit Tests&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mock &lt;strong&gt;all dependencies&lt;/strong&gt; to isolate code.&lt;/td&gt;
&lt;td&gt;Rarely used. Check indirect side effects.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Integration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mock &lt;strong&gt;external services&lt;/strong&gt; (e.g., APIs).&lt;/td&gt;
&lt;td&gt;Spy on &lt;strong&gt;internal logic&lt;/strong&gt; (e.g., logging).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Key Differences&lt;/strong&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;&lt;code&gt;mock&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;spyOn&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Replaces the original function.&lt;/td&gt;
&lt;td&gt;Retains original behavior by default.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scope&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Applies to entire modules or functions.&lt;/td&gt;
&lt;td&gt;Works on individual object methods.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cleanup&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Auto-reset with Vitest config.&lt;/td&gt;
&lt;td&gt;Manually restore with &lt;code&gt;mockRestore()&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Combining Mocks and Spies&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In complex scenarios, mix both tools:&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="c1"&gt;// Mock an external API&lt;/span&gt;
&lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/services/payment&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;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;mockResolvedValue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="c1"&gt;// Spy on an internal validator&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validateSpy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;validateCard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;processes payment with valid card&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="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;submitPayment&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;card&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4111 1111 1111 1111&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;validateSpy&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveReturnedWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveBeenCalled&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;h3&gt;
  
  
  &lt;strong&gt;TypeScript Pro Tips&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Type-Safe Mocks&lt;/strong&gt;
Use &lt;code&gt;MockedFunction&lt;/code&gt; or &lt;code&gt;MockedObject&lt;/code&gt; for better type inference:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/services/api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/services/api&lt;/span&gt;&lt;span class="dl"&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;mockedFetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mocked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Type-safe mock!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Spy Assertions&lt;/strong&gt;
Add type assertions if needed:
&lt;/li&gt;
&lt;/ol&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;spy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;vi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;log&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;MockedFunction&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&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="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;strong&gt;Final Advice&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unit Tests&lt;/strong&gt;: Mock aggressively to isolate components.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration Tests&lt;/strong&gt;: Spy to validate interactions, mock only externals.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always Restore Spies&lt;/strong&gt;: Use &lt;code&gt;afterEach(() =&amp;gt; vi.restoreAllMocks())&lt;/code&gt; to avoid test pollution.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By mastering &lt;code&gt;mock&lt;/code&gt; and &lt;code&gt;spyOn&lt;/code&gt;, you’ll write tests that are &lt;strong&gt;faster&lt;/strong&gt;, &lt;strong&gt;more reliable&lt;/strong&gt;, and &lt;strong&gt;easier to debug&lt;/strong&gt;. Happy testing! 🚀  &lt;/p&gt;




&lt;p&gt;&lt;em&gt;Got questions? Drop them in the comments below!&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Follow for more Vitest and TypeScript tips!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>vitest</category>
      <category>typescript</category>
      <category>testing</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Stages of Git Hook Execution Visualization</title>
      <dc:creator>Axmin Shrestha</dc:creator>
      <pubDate>Wed, 06 Mar 2024 14:14:51 +0000</pubDate>
      <link>https://dev.to/axsh/visualizing-the-stages-of-git-hook-execution-56b8</link>
      <guid>https://dev.to/axsh/visualizing-the-stages-of-git-hook-execution-56b8</guid>
      <description>&lt;p&gt;Here's a brief explanation of each hook:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                +--------------------+
                |   Pre-Commit Hook  |
                +--------------------+
                          |
                          v
                +--------------------+
                |   Commit-Msg Hook  |
                +--------------------+
                          |
                          v
                +--------------------+
                |     Commit Hook    |
                +--------------------+
                          |
                          v
                +--------------------+
                |  Pre-Rebase Hook   |
                +--------------------+
                          |
                          v
         +-------------------------------+
         |            Rebase             |
         |           (Pre-Rebase,        |
         |       Post-Rebase Hooks)      |
         +-------------------------------+
                          |
                          v
                +--------------------+
                |   Post-Rebase Hook |
                +--------------------+
                          |
                          v
                +--------------------+
                |   Pre-Receive Hook |
                +--------------------+
                          |
                          v
                +--------------------+
                |    Update Hook     |
                +--------------------+
                          |
                          v
                +--------------------+
                |   Post-Receive Hook|
                +--------------------+
                          |
                          v
                +--------------------+
                |   Post-Commit Hook |
                +--------------------+
                          |
                          v
                +--------------------+
                |   Post-Merge Hook  |
                +--------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The commit-msg hook runs after the commit message has been entered and before the commit is recorded. This hook can be used to validate the commit message format, enforce commit message conventions, or perform any other checks or modifications related to the commit message.&lt;/p&gt;

&lt;p&gt;The commit-msg hook receives the path to the temporary file containing the commit message as an argument. If the script exits with a non-zero status, the commit operation will be aborted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pre-Commit Hook&lt;/strong&gt;: Runs before you commit any changes to the local repository. It can be used to validate the commit message, check code style, run tests, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commit Hook&lt;/strong&gt;: Runs after the commit data has been committed to the local repository. It can be used for tasks like updating a commit message template or firing a deployment script.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pre-Rebase Hook&lt;/strong&gt;: Runs before a rebase operation starts. It can be used for tasks like stopping the rebase if certain conditions are met.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rebase Hooks&lt;/strong&gt;: Several hooks are available during the rebase operation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;pre-rebase&lt;/strong&gt;: Runs before the rebase operation starts.&lt;br&gt;
&lt;strong&gt;post-rebase&lt;/strong&gt;: Runs after the rebase operation completes successfully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post-Rebase Hook&lt;/strong&gt;: Runs after a successful rebase operation.&lt;br&gt;
&lt;strong&gt;Pre-Receive Hook&lt;/strong&gt;: Runs on the remote repository before any references are updated by the git push command. It can be used to enforce repository policies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update Hook&lt;/strong&gt;: Runs on the remote repository after the references have been updated by the git push command. It can be used to update external systems or triggers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post-Receive Hook&lt;/strong&gt;: Runs on the remote repository after the references have been updated by the git push command. It can be used for deployment scripts or notifications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post-Commit Hook&lt;/strong&gt;: Runs after a successful commit operation.&lt;br&gt;
&lt;strong&gt;Post-Merge Hook&lt;/strong&gt;: Runs after a successful merge operation.&lt;/p&gt;

</description>
      <category>git</category>
      <category>hooks</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>9 Key Rules for Using Git</title>
      <dc:creator>Axmin Shrestha</dc:creator>
      <pubDate>Fri, 21 Jul 2023 11:23:36 +0000</pubDate>
      <link>https://dev.to/axsh/9-key-rules-for-using-git-11k5</link>
      <guid>https://dev.to/axsh/9-key-rules-for-using-git-11k5</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wc37viodepjloow6syu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wc37viodepjloow6syu.jpg" alt="Image description" width="698" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are some important rules to follow when using Git:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Work on a feature branch:&lt;/strong&gt; This is important because it means you do all your work in a separate branch, not the main one. It lets you submit more than one pull request without any mix-ups. Plus, you can make changes without risking any instability in the master branch with unfinished code. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Always branch out from develop:&lt;/strong&gt; By doing this, you make sure that the code in the master branch can be used for releases almost always without any problems. (This might not be necessary for some projects.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Don't push directly into develop or master branch. Instead, make a Pull Request:&lt;/strong&gt; This lets your team know that you've finished a feature. It also makes it easy for your peers to review your code and provides a space to discuss the feature you're proposing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Update your local develop branch and do an interactive rebase before pushing your feature and making a Pull Request:&lt;/strong&gt; This merges in the requested branch (master or develop) and puts the commits you've made locally at the top of the history. This means the history will be neat and tidy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Solve any conflicts while rebasing and before making a Pull Request.&lt;/strong&gt; When you rebase your branch before a Pull Request, you're integrating changes from one branch into another. During this process, conflicts may arise if Git can't decide how to merge the changes. It's crucial to resolve these conflicts during the rebase, before creating your Pull Request. This way, you ensure a clean, conflict-free branch that can be smoothly merged into the main codebase. Resolving conflicts early avoids potential issues down the line and facilitates a faster, more efficient review process for your Pull Request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Delete your local and remote feature branches after they've been merged:&lt;/strong&gt; This stops your list of branches from getting cluttered with branches you're not using anymore. It also makes sure you only merge the branch back into master or develop once.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Before making a Pull Request, check your feature branch to make sure it's working properly and passes all tests (including style checks):&lt;/strong&gt; This is because you're about to add your code to a stable branch. If your tests fail, there's a high chance the destination branch will fail too. Also, doing a style check before making a Pull Request helps keep everything readable and makes sure any formatting fixes are separate from the actual changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use .gitignore file:&lt;/strong&gt; This file already has a list of system files that you shouldn't include in your remote repository. It also excludes certain folders and files for most editors, as well as most common dependency folders.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Protect your develop and master branch:&lt;/strong&gt; This keeps your ready-to-go branches safe from unexpected changes. &lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it! By following these rules, you can make sure your Git workflow is smooth and efficient.&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>development</category>
    </item>
    <item>
      <title>Test-Driven Development (TDD) with React/Nextjs</title>
      <dc:creator>Axmin Shrestha</dc:creator>
      <pubDate>Fri, 14 Jul 2023 21:07:47 +0000</pubDate>
      <link>https://dev.to/axsh/test-driven-development-tdd-with-reactnextjs-pb9</link>
      <guid>https://dev.to/axsh/test-driven-development-tdd-with-reactnextjs-pb9</guid>
      <description>&lt;p&gt;Test-driven development (TDD) with a React frontend that uses libraries like react-query, react-table, Tailwind CSS, and Mock Service Worker (MSW) involves writing tests that assert the behavior of your application. Here are some areas you might consider when writing your tests:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Components:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use &lt;strong&gt;Jest/vitest&lt;/strong&gt; and &lt;strong&gt;React Testing Library&lt;/strong&gt; for testing components. Assert that components render correctly based on different props.&lt;br&gt;
With &lt;strong&gt;react-table&lt;/strong&gt;, test that your table components render the expected data and support the necessary interactions, such as sorting or filtering.&lt;br&gt;
API Interactions:&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;react-query&lt;/strong&gt;, you can test your query and mutation functions to ensure they behave as expected. This includes how your app reacts to success, error, and loading states.&lt;br&gt;
&lt;strong&gt;MSW&lt;/strong&gt; allows you to create a mock server in the browser. Use this to simulate API responses and errors for your tests, ensuring your app behaves correctly given different server responses.&lt;br&gt;
Styling and Layout:&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;Tailwind&lt;/strong&gt;, since the focus is more on utility classes and less on custom styles, it's less likely that you need to write specific tests for styles.&lt;br&gt;
You can still perform visual regression testing using tools like &lt;strong&gt;Cypress&lt;/strong&gt;, &lt;strong&gt;Jest Snapshot&lt;/strong&gt;, or &lt;strong&gt;Storybook&lt;/strong&gt; to ensure your UI does not change unexpectedly.&lt;br&gt;
You can also use accessibility testing tools to ensure your site is accessible, which is particularly important if you are heavily customizing the styles.&lt;br&gt;
Integration and End-to-End tests:&lt;/p&gt;

&lt;p&gt;Once you have the individual units of your app tested, write some integration tests to make sure they work well together.&lt;br&gt;
Tools like &lt;strong&gt;Cypress&lt;/strong&gt; or &lt;strong&gt;Puppeteer/Playwright&lt;/strong&gt; can be used to automate browser-based interactions, testing flows that involve several components.&lt;br&gt;
Simulate user interactions like button clicks, form submissions, etc., and check if the app behaves as expected.&lt;br&gt;
Edge Cases and Error Handling:&lt;/p&gt;

&lt;p&gt;Make sure you have tests for any edge cases you can think of.&lt;br&gt;
It's especially important to test your error handling to ensure your app can recover gracefully from errors.&lt;/p&gt;

&lt;p&gt;Remember, TDD is about writing your tests first and then writing the code to make those tests pass. So you would first write tests for a small piece of functionality, run the tests to make sure they fail, then write the code to make them pass, and finally refactor the code while keeping the tests green. This cycle is often referred to as Red-Green-Refactor.&lt;/p&gt;

</description>
      <category>react</category>
      <category>tdd</category>
      <category>typescript</category>
      <category>reactjsdevelopment</category>
    </item>
    <item>
      <title>How to avoid Technical Debt? Discover the foolproof strategies to steer clear of technical debt.</title>
      <dc:creator>Axmin Shrestha</dc:creator>
      <pubDate>Fri, 14 Jul 2023 21:03:20 +0000</pubDate>
      <link>https://dev.to/axsh/how-to-avoid-technical-debt-discover-the-foolproof-strategies-to-steer-clear-of-technical-debt-2kkn</link>
      <guid>https://dev.to/axsh/how-to-avoid-technical-debt-discover-the-foolproof-strategies-to-steer-clear-of-technical-debt-2kkn</guid>
      <description>&lt;p&gt;In the fast-paced world of technology, staying ahead of the curve is essential for any startup. But amidst the excitement of innovation and growth, there lurks a silent menace known as technical debt. To steer clear of this treacherous trap that can undermine your success, it's crucial to adopt a strategic approach. By following a set of best practices, you can ensure that your codebase remains clean, maintainable, and scalable, paving the way for long-term growth and prosperity.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Educate non-technical team members about technical debt and its consequences.&lt;/li&gt;
&lt;li&gt;Hire technical staff or consultants with web development experience.&lt;/li&gt;
&lt;li&gt;Prioritize thorough planning that considers technical debt mitigation.&lt;/li&gt;
&lt;li&gt;Establish coding standards and guidelines for developers to follow.&lt;/li&gt;
&lt;li&gt;Conduct regular code reviews to identify potential technical debt.&lt;/li&gt;
&lt;li&gt;Implement a strong testing strategy with automated tests.&lt;/li&gt;
&lt;li&gt;Leverage external resources like online communities and conferences.&lt;/li&gt;
&lt;li&gt;Encourage continuous learning and skill development.&lt;/li&gt;
&lt;li&gt;Allocate time and resources for addressing existing technical debt.&lt;/li&gt;
&lt;li&gt;Foster a collaborative culture across the team.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Avoiding technical debt is crucial for long-term success in software development. By educating team members, hiring technical expertise, planning effectively, setting coding standards, conducting code reviews, prioritizing automated testing, utilizing external resources, emphasizing continuous learning, planning for debt repayment, and fostering a culture of collaboration, startups can mitigate technical debt and maintain a healthy codebase. With a proactive approach and commitment to these best practices, startups can ensure sustainable growth and minimize the risks associated with technical debt.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
