<?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: Caio Ragazzi</title>
    <description>The latest articles on DEV Community by Caio Ragazzi (@caioragazzi).</description>
    <link>https://dev.to/caioragazzi</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%2F319829%2F76670010-6c7e-4bff-b277-52859a532797.jpg</url>
      <title>DEV Community: Caio Ragazzi</title>
      <link>https://dev.to/caioragazzi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/caioragazzi"/>
    <language>en</language>
    <item>
      <title>Mastering Angular Templates</title>
      <dc:creator>Caio Ragazzi</dc:creator>
      <pubDate>Mon, 05 Feb 2024 20:27:28 +0000</pubDate>
      <link>https://dev.to/caioragazzi/mastering-angular-templates-3ne0</link>
      <guid>https://dev.to/caioragazzi/mastering-angular-templates-3ne0</guid>
      <description>&lt;p&gt;Hello Devs,&lt;/p&gt;

&lt;p&gt;If you're an Angular developer, chances are you've worked with PrimeNG. I've been using it for some time, and there's always been one aspect that caught my attention: TEMPLATES!&lt;/p&gt;

&lt;p&gt;Take, for instance, the PrimeNG Card component. This component provides a &lt;strong&gt;&lt;em&gt;header&lt;/em&gt;&lt;/strong&gt; property where you can pass a string, but the real power lies in customizing the header to your liking using a &lt;strong&gt;&lt;em&gt;pTemplate&lt;/em&gt;&lt;/strong&gt;. It functions as illustrated below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p-card&lt;/span&gt; &lt;span class="na"&gt;header=&lt;/span&gt;&lt;span class="s"&gt;"Car Header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ng-template&lt;/span&gt; &lt;span class="na"&gt;pTemplate=&lt;/span&gt;&lt;span class="s"&gt;"header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Card"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"http://fake.url.png"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ng-template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/p-card&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's pretty awesome, right?&lt;br&gt;
If you're as curious as I am, you probably want to dive into the inner workings of this template feature. No worries, my friend – I've got your back. I've explored and figured it out, and now you can too. Here's how it works, and you'll be able to apply this strategy in your components as well.&lt;/p&gt;

&lt;p&gt;The core idea is to capture the content inside the &lt;em&gt;&lt;strong&gt;ng-template&lt;/strong&gt;&lt;/em&gt; and render it at a specific location within our component. But not just any template – we want a specific one. In the example below, our aim is to render only the template with the directive &lt;strong&gt;&lt;em&gt;myTemplate="header"&lt;/em&gt;&lt;/strong&gt; in our component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;my-component&lt;/span&gt; &lt;span class="na"&gt;header=&lt;/span&gt;&lt;span class="s"&gt;"Car Header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ng-template&lt;/span&gt; &lt;span class="na"&gt;myTemplate=&lt;/span&gt;&lt;span class="s"&gt;"header"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Simple button&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ng-template&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/my-component&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First things first, let's create the &lt;em&gt;&lt;strong&gt;myTemplate&lt;/strong&gt;&lt;/em&gt; directive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Directive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TemplateRef&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;@angular/core&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="nd"&gt;Directive&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[myTemplate]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyTemplateDirective&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myTemplate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TemplateRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;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;getType&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&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;As we can see, it's a straightforward structural directive (more on structure directives here: &lt;a href="https://angular.io/guide/structural-directives#creating-a-structural-directive"&gt;Angular.io&lt;/a&gt;) with a single input to receive the type (in our case, "header"), and a function named &lt;em&gt;&lt;strong&gt;getType&lt;/strong&gt;&lt;/em&gt; that returns the input value (I'll explain the reason for this function later in the article).&lt;/p&gt;

&lt;p&gt;Now, let's move on to creating the component &lt;em&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;AfterContentInit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;ContentChildren&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;QueryList&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;TemplateRef&lt;/span&gt;&lt;span class="p"&gt;,&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;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MyTemplateDirective&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;../my-template-directive/my-template-directive&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="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./my-component.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./my-component.component.scss&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyComponent&lt;/span&gt; &lt;span class="kr"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;AfterContentInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;headerTemplate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TemplateRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ContentChildren&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MyTemplateDirective&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;templates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;QueryList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyTemplateDirective&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;ngAfterContentInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;templates&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;QueryList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyTemplateDirective&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;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&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;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getType&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;header&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headerTemplate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&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;Let's break down this component:&lt;/p&gt;

&lt;p&gt;1) We require a property (&lt;em&gt;&lt;strong&gt;headerTemplate&lt;/strong&gt;&lt;/em&gt;) with the type &lt;em&gt;&lt;strong&gt;TemplateRef&lt;/strong&gt;&lt;/em&gt; to store the template that is being passed to the component.&lt;br&gt;
2) We need a property (&lt;em&gt;&lt;strong&gt;templates&lt;/strong&gt;&lt;/em&gt;) to store all the templates that have our custom directive assigned to them. In our case, this property is 'templates' and is decorated with &lt;em&gt;&lt;strong&gt;@ContentChildren(MyTemplate)&lt;/strong&gt;&lt;/em&gt; (you can find more about the &lt;em&gt;&lt;strong&gt;@ContentChildren&lt;/strong&gt;&lt;/em&gt; decorator &lt;a href="https://angular.io/api/core/ContentChildren"&gt;Angular.io&lt;/a&gt;)&lt;br&gt;
3) With the help of the lifecycle hook &lt;em&gt;&lt;strong&gt;AfterContentInit&lt;/strong&gt;&lt;/em&gt; (you can learn more about the &lt;em&gt;&lt;strong&gt;AfterContentInit&lt;/strong&gt;&lt;/em&gt; lifecycle hook &lt;a href="https://angular.io/api/core/AfterContentInit"&gt;Angular.io&lt;/a&gt;), we iterate over all the templates and call the function &lt;em&gt;&lt;strong&gt;getType&lt;/strong&gt;&lt;/em&gt; to retrieve only the template with the directive "header," storing it in the &lt;em&gt;&lt;strong&gt;headerTemplate&lt;/strong&gt;&lt;/em&gt; property.&lt;/p&gt;

&lt;p&gt;That wraps up the TypeScript part of our component. Essentially, we're searching for all &lt;em&gt;&lt;strong&gt;ng-templates&lt;/strong&gt;&lt;/em&gt; with our custom directive that were passed to &lt;em&gt;&lt;strong&gt;MyComponent&lt;/strong&gt;&lt;/em&gt; and extracting only the one with the 'header' input. &lt;/p&gt;

&lt;p&gt;Now that we have the template in the &lt;em&gt;&lt;strong&gt;headerTemplate&lt;/strong&gt;&lt;/em&gt; property, let's proceed to display it in the HTML. Take a look at the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"headerTemplate"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Template content&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;ng-container&lt;/span&gt; &lt;span class="na"&gt;*ngTemplateOutlet=&lt;/span&gt;&lt;span class="s"&gt;"headerTemplate"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ng-container&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;--------------------------&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Footer without template&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's as simple as that. By utilizing the Angular structural directive &lt;em&gt;&lt;strong&gt;ngTemplateOutlet&lt;/strong&gt;&lt;/em&gt; (you can find more information on &lt;em&gt;&lt;strong&gt;ngTemplateOutlet&lt;/strong&gt;&lt;/em&gt; &lt;a href="https://angular.io/api/common/NgTemplateOutlet"&gt;Angular.io&lt;/a&gt;) we use an &lt;strong&gt;&lt;em&gt;ng-container&lt;/em&gt;&lt;/strong&gt; to pass our &lt;strong&gt;&lt;em&gt;headerTemplate&lt;/em&gt;&lt;/strong&gt; as input with '*ngTemplateOutlet="headerTemplate"'. This allows us to dynamically render the template within our component.&lt;/p&gt;

&lt;p&gt;This strategy empowers us to build highly customizable and flexible components. By implementing this approach, we ensure a robust component that only renders templates specified by the custom directive. It provides a level of control and encapsulation, allowing developers to create versatile components while maintaining a clear structure and limiting the rendering scope to specific templates. This can lead to more maintainable and modular code.&lt;/p&gt;

&lt;p&gt;What are your thoughts on this design?&lt;br&gt;
In what ways could this design be improved or extended?&lt;/p&gt;

&lt;p&gt;If you want to explore the code for this example, you can find it in the GitHub repository: &lt;a href="https://github.com/CaioRagazzi/mastering-angular-templates"&gt;Angular Templates GitHub Repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you so much for reading this post, everyone! As always, I wish you happy coding!&lt;/p&gt;

&lt;p&gt;See you!&lt;/p&gt;

</description>
      <category>angular</category>
    </item>
    <item>
      <title>Comprehensive Unit Testing: A Line-by-Line Approach</title>
      <dc:creator>Caio Ragazzi</dc:creator>
      <pubDate>Mon, 11 Sep 2023 20:25:07 +0000</pubDate>
      <link>https://dev.to/caioragazzi/comprehensive-unit-testing-a-line-by-line-approach-35ol</link>
      <guid>https://dev.to/caioragazzi/comprehensive-unit-testing-a-line-by-line-approach-35ol</guid>
      <description>&lt;p&gt;Hello Dev's,&lt;/p&gt;

&lt;p&gt;I hope you are having a wonderful day.&lt;/p&gt;

&lt;p&gt;In this article, I'd like to share my recent approach to unit testing. I believe this method is highly effective in testing my classes and ensuring comprehensive coverage of my business rules. Additionally, I hope this article can provide you with valuable insights or even an opportunity to exchange tips and ideas for improving our testing practices.&lt;/p&gt;

&lt;p&gt;Before we dive into the specifics, let me introduce the tools that will be used in this example. (Perhaps in the future, I can create a separate article dedicated to explaining why I prefer these tools):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;xUnit -&amp;gt; &lt;a href="https://xunit.net/" rel="noopener noreferrer"&gt;https://xunit.net/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AutoFixture -&amp;gt; &lt;a href="https://autofixture.github.io/" rel="noopener noreferrer"&gt;https://autofixture.github.io/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;FluentAssertions -&amp;gt; &lt;a href="https://fluentassertions.com/" rel="noopener noreferrer"&gt;https://fluentassertions.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AutoMock -&amp;gt; &lt;a href="https://github.com/automock/automock" rel="noopener noreferrer"&gt;https://github.com/automock/automock&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Method being tested
&lt;/h2&gt;

&lt;p&gt;Let's take a simple example of a method that adds an entity to a database. Typically, this method might look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeerDtoResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;AddBeer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BeerDtoRequest&lt;/span&gt; &lt;span class="n"&gt;beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;beer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_mapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Beer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;beer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewGuid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_beerRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;beer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_mapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeerDtoResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;beer&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;A straightforward method that maps a request DTO to an entity, adds a GUID to the ID, inserts it into the database, and returns a mapped DTO.&lt;/p&gt;

&lt;h2&gt;
  
  
  Objective
&lt;/h2&gt;

&lt;p&gt;My primary objective is to comprehensively test every line of the method, a practice I affectionately call "Shielding the Method." Why do I adhere to this principle? Quite simply, if I've written a particular line of code, it's because it serves a purpose, and I want to ensure that it continues to function as intended. Furthermore, whenever we introduce new features or make changes, our tests must evolve in sync with the codebase to maintain its integrity.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do I do it?
&lt;/h2&gt;

&lt;p&gt;To achieve this level of comprehensive testing, I typically begin by creating a base class that houses commonly used methods. I leverage the power of AutoMock and AutoFixture to streamline this process. Here's a glimpse of what this base class might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BaseTest&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Fixture&lt;/span&gt; &lt;span class="n"&gt;_fixture&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;AutoMocker&lt;/span&gt; &lt;span class="n"&gt;_mocker&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;CreateFixture&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_fixture&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;CreateManyFixture&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_fixture&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateMany&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;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;A straightforward class that provides you with an instance of AutoMocker and methods to create fixtures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Alright, then my initial approach involves creating a test method that successfully runs the AddBeer method without encountering any errors. This requires us to set up our test class correctly. Here's the reasoning behind this approach:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft6jnz94z5gr8815xjl89.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft6jnz94z5gr8815xjl89.png" alt="Method steps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to create the service instance, generate the DTO that the method expects, set up mocking for the mapping from DTO to entity, mock the repository, and establish mocking for the mapping from entity to DTO. Let's proceed with these steps:&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring the test class
&lt;/h2&gt;

&lt;p&gt;1) Creating the service instance:&lt;/p&gt;

&lt;p&gt;Our &lt;strong&gt;&lt;em&gt;AddBeer&lt;/em&gt;&lt;/strong&gt; method is part of a service. Therefore, our first step is to instantiate this service for testing purposes. To streamline this process and maintain simplicity and speed, I rely on a library called AutoMock. AutoMock helps by creating an instance of the service and resolving all its dependencies. I initialize this service instance in the constructor and assign it to a global variable within the test class. This ensures that the service can be accessed by other test methods. Here's how it's implemented:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;BeerService&lt;/span&gt; &lt;span class="n"&gt;_beerService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;BeerServiceTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_beerService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_mocker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateInstance&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeerService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using the &lt;em&gt;CreateInstance&lt;/em&gt; method, we can specify the type for which we want to create an instance. Just like magic, this method provides us with the desired instance, complete with all of its resolved dependencies.&lt;/p&gt;

&lt;p&gt;2) Creating the DTO:&lt;/p&gt;

&lt;p&gt;As this DTO may be utilized by multiple test methods, I typically construct it in the constructor and assign it to a global variable within the test class. To create this DTO efficiently, I rely on AutoFixture, which simplifies the process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;BeerService&lt;/span&gt; &lt;span class="n"&gt;_beerService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;BeerDtoRequest&lt;/span&gt; &lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;BeerServiceTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_beerService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_mocker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateInstance&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeerService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CreateFixture&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this context, we are making use of a helper method from the base class, which utilizes AutoFixture to generate instances of the required classes. We achieve this by invoking the AutoFixture method &lt;strong&gt;&lt;em&gt;Create&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;3) Mocking the first map (DTO to entity)&lt;/p&gt;

&lt;p&gt;To mock the mapping method, we also leverage AutoMock. This can be accomplished by invoking the &lt;strong&gt;&lt;em&gt;GetMock&lt;/em&gt;&lt;/strong&gt; method and then configuring the &lt;strong&gt;&lt;em&gt;Setup&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;Return&lt;/em&gt;&lt;/strong&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;_beer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Beer&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Beer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Brand&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Brand"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Score&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"User"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;_mocker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetMock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Beer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;Returns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this step, it's crucial to create the beer entity and assign it to a global variable within our test class. This entity will be used in future assertions, making it an essential part of our testing setup.&lt;/p&gt;

&lt;p&gt;4) Mocking the repository&lt;/p&gt;

&lt;p&gt;We will apply the same concept here as in step 3, utilizing AutoMock and configuring the &lt;strong&gt;&lt;em&gt;Setup&lt;/em&gt;&lt;/strong&gt;. The only difference is that we don't need to configure the &lt;strong&gt;&lt;em&gt;Return&lt;/em&gt;&lt;/strong&gt; because our repository method &lt;strong&gt;&lt;em&gt;Insert&lt;/em&gt;&lt;/strong&gt; does not return anything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;_mocker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetMock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IBeerRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beer&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5) Mocking the other map (entity to DTO)&lt;/p&gt;

&lt;p&gt;Similar to step 3, we'll once again employ AutoMock, configuring the &lt;strong&gt;&lt;em&gt;Setup&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;Return&lt;/em&gt;&lt;/strong&gt;. Of course, we also need to create an instance of our response, for which we can utilize AutoFixture and assign the result to a global variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;_beerDtoResponse&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CreateFixture&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeerDtoResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="n"&gt;_mocker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetMock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeerDtoResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;_beer&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;Returns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beerDtoResponse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's how the constructor and variables will look like in their final form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;BeerService&lt;/span&gt; &lt;span class="n"&gt;_beerService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;BeerDtoRequest&lt;/span&gt; &lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;BeerDtoResponse&lt;/span&gt; &lt;span class="n"&gt;_beerDtoResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;Beer&lt;/span&gt; &lt;span class="n"&gt;_beer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;BeerServiceTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_beerService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_mocker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateInstance&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeerService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CreateFixture&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="n"&gt;_beer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Beer&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Beer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Brand&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Brand"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Score&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"User"&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="n"&gt;_mocker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetMock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Beer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;Returns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;_mocker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetMock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IBeerRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beer&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="n"&gt;_beerDtoResponse&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CreateFixture&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeerDtoResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;_mocker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetMock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeerDtoResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;_beer&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;Returns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beerDtoResponse&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;That's it, now we have our method ready to be used. Lets start writing our test methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  First test "happy path"
&lt;/h2&gt;

&lt;p&gt;As mentioned earlier, for the first test method, I typically ensure that no exceptions are thrown, often referred to as navigating the "happy path." The method is structured like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ItShouldRunWithoutErrors&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_beerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddBeer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;act&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;NotThrowAsync&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;Let's break down what's happening in this code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We start by invoking our AddBeer method using the service instance we created with AutoMocker, and we assign the result to a Func.&lt;/li&gt;
&lt;li&gt;We utilize FluentAssertion to verify that our function executes without throwing any errors. This is achieved by chaining the methods Should() and NotThrowAsync().&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When we run dotnet test from the command line, we can observe that our first test passes successfully.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1qcdw6gd4onyg4fm50q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1qcdw6gd4onyg4fm50q.png" alt="Test passes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Indeed, we've made significant progress. We now have a callable method that is functional. Our next task is to ensure that every line of our AddBeer method remains intact. If any changes are made, our test methods should break and alert the developer that corrective actions are required. This will help us maintain code integrity and ensure that future modifications are thoroughly tested.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing line by line
&lt;/h2&gt;

&lt;p&gt;For this, let's go line by line in the AddBeer method:&lt;/p&gt;

&lt;p&gt;1) First Line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;beer&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_mapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Beer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To ensure that the first line, where we map the DTO request to an entity, is consistently used with AutoMapper and the same DTO request, we can employ AutoMock. We can use the Verify method and configure it to assert that the method is called with specific parameters and even specify how many times it should be executed. The test method would be structured like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ItShouldMapBeerDtoRequestToBeer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_beerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddBeer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;_mocker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetMock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;Verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Beer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Once&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;In the Verify method, the first parameter specifies how we expect the method to be called, and the second parameter indicates how many times it should be executed. This allows us to precisely define the expected behavior of the method being tested.&lt;/p&gt;

&lt;p&gt;-- Here's the interesting part --&lt;/p&gt;

&lt;p&gt;Imagine someone decides to refactor the &lt;strong&gt;&lt;em&gt;AddBeer&lt;/em&gt;&lt;/strong&gt; method and opts to manually perform the mapping instead of using AutoMapper, something like this (for the sake of example):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtpd3gle7dby2p6qefch.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtpd3gle7dby2p6qefch.png" alt="method refactor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;em&gt;AddBeer&lt;/em&gt;&lt;/strong&gt; method might still work after the refactoring, but the reason we initially chose to use AutoMapper may be due to specific profile configurations or other factors that could potentially alter the method's behavior. However, with our test in place, let's observe what happens when we execute it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdu3w2hjfapne40hqwe3y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdu3w2hjfapne40hqwe3y.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The test result clearly indicates that the AutoMap.Map method was expected to be called, but it wasn't, which is indeed valuable feedback for maintaining the integrity of our code.&lt;/p&gt;

&lt;p&gt;Let's continue with the examination of the AddBeer method. &lt;/p&gt;

&lt;p&gt;2) Second Line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;beer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewGuid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the line where we assign a GUID to our mapped entity's &lt;strong&gt;&lt;em&gt;ID&lt;/em&gt;&lt;/strong&gt; property, we can create a test method to ensure that this line is always executed. Here's an example of how such a test method could be structured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;BeerIdShouldHaveAGUIDAssigned&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_beerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddBeer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;_beer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;NotBeEmpty&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;In this test method, we begin by invoking our &lt;strong&gt;&lt;em&gt;AddBeer&lt;/em&gt;&lt;/strong&gt; method and subsequently verify that _&lt;em&gt;&lt;strong&gt;beer.Id&lt;/strong&gt;&lt;/em&gt; is not empty using the FluentAssert methods &lt;em&gt;&lt;strong&gt;Should()&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;NotBeEmpty()&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This approach serves as an effective safeguard. If, during a refactoring process, someone forgets to assign the GUID, our test method will promptly raise an issue, ensuring that the critical aspect of our code is not overlooked.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1imwmadtlmcpyp7me91.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa1imwmadtlmcpyp7me91.png" alt="removing guid"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F06emtk1kld9aci70mcfr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F06emtk1kld9aci70mcfr.png" alt="test error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3) Third line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_beerRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;beer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For testing the line where we call the repository and insert our entity into the database, we can utilize the AutoMock library to verify that the Insert method is invoked with the desired parameter and the correct number of times. Here's an example of how such a test method could be structured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ItShouldInserBeer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_beerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddBeer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;_mocker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetMock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IBeerRepository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;Verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Insert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beer&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Once&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;If someone accidentally removes this line from our &lt;em&gt;&lt;strong&gt;AddBeer&lt;/strong&gt;&lt;/em&gt; method, our test will promptly identify the omission and trigger an exception. This acts as a safety measure against unintentional code alterations or deletions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe0gso3lc2jxhf6c3tbi9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe0gso3lc2jxhf6c3tbi9.png" alt="remove line"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh5fgrf200r01j3hulbcs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh5fgrf200r01j3hulbcs.png" alt="test error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4) Fourth and last line&lt;/p&gt;

&lt;p&gt;This line provides an opportunity to create multiple tests. We can use it to verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether the mapping is executed correctly.&lt;/li&gt;
&lt;li&gt;If the return type matches our expected type.&lt;/li&gt;
&lt;li&gt;The contents of the DTO being returned.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By segmenting these aspects into separate tests, we can thoroughly assess the functionality of this line in our AddBeer method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ItShoulMapBeerDtoResponseToBeer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_beerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddBeer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;_mocker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetMock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IMapper&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;Verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeerDtoResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;_beer&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Once&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ItShouldReturnTypeBeerDtoResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_beerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddBeer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;BeOfType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeerDtoResponse&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Fact&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ItShouldReturnBeerDtoResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_beerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddBeer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beerDtoRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Be&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_beerDtoResponse&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;For these tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To ensure that the mapping is executed, we employ the AutoMock Verify method as we did previously, validating that the Map method is called once.&lt;/li&gt;
&lt;li&gt;For type validation, we use FluentAssertion's BeOfType method to confirm that the return type matches our expected type.&lt;/li&gt;
&lt;li&gt;To verify that the returned beer matches our expectations, we use FluentAssertion's Be method.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;When I approach testing a method, I follow a systematic approach where I create one test method for each line of the method being tested, adhering to the Single Responsibility Principle (SRP). Additionally, I often create one test class for each method I want to test. For instance, if a service class contains four methods (representing simple CRUD operations), I'll likely have four test classes, each dedicated to one method.&lt;/p&gt;

&lt;p&gt;I usually start my tests by creating a basic test that runs the method under test and ensures it doesn't throw any errors. Afterward, I meticulously test each line of the method, as we've explored earlier.&lt;/p&gt;

&lt;p&gt;When it comes to naming my test methods, I aim for maximum specificity. I don't worry about the length of the name; instead, I want it to clearly explain what the method is testing, and I stick to testing just one thing per method.&lt;/p&gt;

&lt;p&gt;As you can see, we were able to create seven test methods for a straightforward AddBeer function, which aligns perfectly with the goal of unit testing. The aim here is to have as many tests as possible for a single unit, ensuring comprehensive coverage and robust validation.&lt;/p&gt;

&lt;p&gt;I hope this approach proves helpful to you in your testing efforts. If you have any insights or feedback to share, please feel free to do so. &lt;/p&gt;

&lt;p&gt;Wishing you a fantastic day!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>unittest</category>
    </item>
    <item>
      <title>.NET + Secret Manager</title>
      <dc:creator>Caio Ragazzi</dc:creator>
      <pubDate>Sun, 03 Sep 2023 08:15:04 +0000</pubDate>
      <link>https://dev.to/caioragazzi/net-secret-manager-353a</link>
      <guid>https://dev.to/caioragazzi/net-secret-manager-353a</guid>
      <description>&lt;p&gt;Hello again, fellow developers!&lt;/p&gt;

&lt;p&gt;What a beautiful Sunday to dive into the topic of security! I understand that many of you are in the process of developing fantastic .NET applications with a myriad of integration services like Google Cloud Platform, databases, APIs, and more. Each integration brings its set of keys, passwords, and sensitive information, all residing in your appsettings.json file, just waiting for the wrong hands to get hold of them, potentially compromising your integrations and security.&lt;/p&gt;

&lt;p&gt;Imagine this scenario: you've just completed an incredible feature and are eager to push it to your public GitHub repository. But then, a moment of panic hits you as you remember that your appsettings.json contains sensitive data. You can't risk exposing it to the public. So, you're faced with the tedious task of scrubbing your configuration clean before publishing. And to make matters worse, every time you start working again, you must reconfigure everything or maintain a separate copy of your appsettings on your local PC.&lt;/p&gt;

&lt;p&gt;But fear not, my friends, for the Microsoft team has come to the rescue with something truly remarkable: &lt;strong&gt;user secrets&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;What is it?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Dotnet user secrets is a command-line tool that securely stores sensitive data in a separate location from your project. The beauty of it is that you can easily access this sensitive information without needing to make any changes to your project itself. Intrigued?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;How does it work?&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Setting up user secrets is incredibly straightforward, I can assure you! To get started, all you need to do is run the init command within your project folder.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet user-secrets init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After running the init command, you'll notice that your .csproj file will have a UserSecretsId element inside the PropertyGroup, something along these lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;PropertyGroup&amp;gt;
  &amp;lt;TargetFramework&amp;gt;netcoreapp3.1&amp;lt;/TargetFramework&amp;gt;
  &amp;lt;UserSecretsId&amp;gt;79a3edd0-2092-40a2-a04d-dcb46d5ca9ed&amp;lt;/UserSecretsId&amp;gt;
&amp;lt;/PropertyGroup&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you've initiated user secrets, you can start adding your "secrets." To add a new secret, use the set command, and make sure to include a key-value attribute like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet user-secrets set "ConnectionString" "XYz"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can consider secrets as similar to our AppSettings.json. For instance, let's say we have the following item configured in it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxjwj3116xwgzbqfrdbhs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxjwj3116xwgzbqfrdbhs.png" alt="appsettings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can effortlessly execute the following commands to store the two connection strings in our secrets vault:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet user-secrets set "ConnectionStrings:MySql" "server=127.0.0.1;uid=root;pwd=12345;database=test"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet user-secrets set "ConnectionStrings:SQL" "Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As we can see, we have literal objects in our key-value pairs. In this example, we define two different properties (MySQL and SQL) with distinct values.&lt;/p&gt;

&lt;p&gt;After configuring these key-value pairs, you could completely remove the ConnectionStrings section from the AppSettings, and your code would still function seamlessly. Isn't that amazing?&lt;/p&gt;

&lt;p&gt;Now that you've added your secrets to your vault, you might wonder how to access them. Well, the beauty of it is that it doesn't change the way you access your AppSettings. You can still inject the IConfiguration interface into your class and access it in the same familiar way.&lt;/p&gt;

&lt;p&gt;You could achieve a similar outcome by adding your keys to environment variables, but with the dotnet user-secrets tool, everything becomes more convenient and streamlined for our day-to-day tasks.&lt;/p&gt;

&lt;p&gt;It's pretty awesome, right? If you want to dive deeper into this tool, you can find more information here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-7.0&amp;amp;tabs=linux" rel="noopener noreferrer"&gt;https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-7.0&amp;amp;tabs=linux&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are many more features described that can be incredibly useful for you.&lt;/p&gt;

&lt;p&gt;For now, that's all, my friends. I hope you're having a fantastic day!&lt;/p&gt;

&lt;p&gt;Keep coding, and I'll see you around!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>cli</category>
      <category>appsettings</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Google Storage + .NET 7</title>
      <dc:creator>Caio Ragazzi</dc:creator>
      <pubDate>Tue, 15 Aug 2023 19:59:38 +0000</pubDate>
      <link>https://dev.to/caioragazzi/google-storage-net-7-5h2a</link>
      <guid>https://dev.to/caioragazzi/google-storage-net-7-5h2a</guid>
      <description>&lt;p&gt;Hello, fellow dev friends. I hope you all are doing great.&lt;/p&gt;

&lt;p&gt;When I am writing this article is a national holiday here in Portugal (Assumption of Mary) 🇵🇹 and how to enjoy most of this beautiful day? Going to the park? beach? eat some delicious pastries? Not at all! Let's write my first (yesss that's it, my first!) post here at dev.to!&lt;/p&gt;

&lt;p&gt;Being a Brazilian leaving in Portugal is quite easy, to be honest (mostly because of the language), but writing here for developers all over the world, well, this can be a bit tricky for me! But let's try it out!&lt;br&gt;
Enough of introductions and let's start talking about what is actually saying in the title!&lt;/p&gt;

&lt;p&gt;In the last few days, I have started learning some Google Cloud concepts through &lt;a href="https://www.cloudskillsboost.google/"&gt;https://www.cloudskillsboost.google/&lt;/a&gt; (by the way, such an amazing platform to learn GCP). And one of the first concepts they teach us is Google Cloud Storage. And for me, the best way to learn those concepts is by applying them in a practical way.&lt;/p&gt;

&lt;p&gt;So First I created a really small .NET 7 Class Library to upload some files in Cloud Storage Bucket.&lt;/p&gt;

&lt;p&gt;Let's start by creating a new Class Library project. Here I am using the &lt;strong&gt;C# Dev Kit&lt;/strong&gt; extension for Visual Code to keep things simple (I could also use the dotnet CLI):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--l92kiEcr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ds8i0rowa4wzubqg1nic.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--l92kiEcr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ds8i0rowa4wzubqg1nic.png" alt="Visual Code New Project Creation" width="645" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Es1O8cPB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nyj1trtfwrtmixf9bt60.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Es1O8cPB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nyj1trtfwrtmixf9bt60.png" alt="Visual Code New Project Type Class Library Creation" width="648" height="36"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is cool about the &lt;strong&gt;C# Dev Kit&lt;/strong&gt; is that when you create a Class Library in an empty folder it also creates the solution for you:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--o6Kqu8Lb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gof20dv88p9epoaqlrfd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--o6Kqu8Lb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gof20dv88p9epoaqlrfd.png" alt="VSCode Solution Explorer side tab visualization" width="368" height="197"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is where things really got me excited, because I thought the process to import a file to the GCP Cloud Storage would be a bit complex, but it is actually not.&lt;/p&gt;



&lt;p&gt;⚠️ Before we continue is important to go through the following steps:&lt;/p&gt;

&lt;p&gt;We need to authenticate our application in the GCP by using the Application Default Credentials or commonly known as ADC. There are a couple of ways of doing it but for me, the easier is by using the gcloud CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gcloud auth application-default login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to know more about the command above, you can visit the URL:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login"&gt;https://cloud.google.com/sdk/gcloud/reference/auth/application-default/login&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But basically, you will need to follow some steps to obtain user access credentials and then the CLI will place it in a location where the ADC will get it.&lt;/p&gt;




&lt;p&gt;Now we can start configuring our project. We will need to install the Google Cloud Storage V1 Nuget Package:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.nuget.org/packages/Google.Cloud.Storage.V1"&gt;https://www.nuget.org/packages/Google.Cloud.Storage.V1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And then with a couple of lines, we can easily upload files to buckets in Google Cloud:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class FileUploader
{
    public async Task&amp;lt;string&amp;gt; UploadFile(string base64String)
    {
        var client = await StorageClient.CreateAsync();

        var bucket = await client.GetBucketAsync("bucket name");

        var bytes = Convert.FromBase64String(base64String);
        var dataObject = await client.UploadObjectAsync(bucket.Name, "folder/fileName.png", "text/plain", new MemoryStream(bytes));

        return dataObject.Id;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's go through line by line to see what is happening:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var client = await StorageClient.CreateAsync();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;First, we use this static method CreateAsync to get an instance of the class StorageClient.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var bucket = await client.GetBucketAsync("bucket name");&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here we are getting an instance of an existing bucket by its name, but if you don't have a bucket yet, you could create a new one using the method &lt;strong&gt;CreateBucketAsync&lt;/strong&gt; which will also return a bucket instance.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var bytes = Convert.FromBase64String(base64String);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then we are getting a little help from the method FromBase64String to convert a "probably" base64 photo to an array of bytes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var dataObject = await client.UploadObjectAsync(bucket.Name, "folder/fileName.png", "text/plain", new MemoryStream(bytes));&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And to finally upload the file, we pass three parameters to the method UploadObjectAsync&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bucket Name.&lt;/li&gt;
&lt;li&gt;File Name (But here you could also organize your bucket with folders by passing the folder name in the string like this "folder1/folder2/filename.png").&lt;/li&gt;
&lt;li&gt;Stream - and that's why we had to convert our base64 string to an array of bytes!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;return dataObject.Id;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And finally, here I just returned the Id of the newly created object, which is basically the ID of the object, including the bucket name, object name, and generation number.&lt;/p&gt;

&lt;p&gt;And that's it, incredible isn't it? With a small effort, we can create a method that will upload some files to a GCP Bucket.&lt;/p&gt;

&lt;p&gt;Thanks a lot, guys! I will try to post more content here so please tell me what you think about this post and if you are in a good day tell me how can I improve it 😄!&lt;/p&gt;

&lt;p&gt;Now I can come back to the holiday and eat some delicious pastries that only Portugal can give to us 🍪 🍰! If you have been here you know what I am talking about (Pastéis de Nata)&lt;/p&gt;

</description>
      <category>googlecloud</category>
      <category>dotnet</category>
    </item>
  </channel>
</rss>
