<?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: Chuen Lee</title>
    <description>The latest articles on DEV Community by Chuen Lee (@ch_lee).</description>
    <link>https://dev.to/ch_lee</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%2F185651%2F59cb8410-ff2b-47b7-96f1-67f003b1d2fb.jpg</url>
      <title>DEV Community: Chuen Lee</title>
      <link>https://dev.to/ch_lee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ch_lee"/>
    <language>en</language>
    <item>
      <title>How to save time writing unit and integration tests with AutoFixture</title>
      <dc:creator>Chuen Lee</dc:creator>
      <pubDate>Thu, 05 Sep 2019 10:03:33 +0000</pubDate>
      <link>https://dev.to/ch_lee/how-to-save-time-writing-unit-and-integration-tests-with-autofixture-ih1</link>
      <guid>https://dev.to/ch_lee/how-to-save-time-writing-unit-and-integration-tests-with-autofixture-ih1</guid>
      <description>&lt;p&gt;Writing Unit and integration tests are generally composed of setting up relevant test data, carrying the actual execution of the test, and finally making assertions. All this can be summarised as the AAA syntax. That is, Arrange, Act, and Assert. &lt;/p&gt;

&lt;p&gt;With &lt;a href="https://github.com/AutoFixture/AutoFixture" rel="noopener noreferrer"&gt;AutoFixture&lt;/a&gt;, it can significantly save you time by taking away the tedious part of stubbing and arranging test data.&lt;/p&gt;

&lt;p&gt;The best way to describe this is to show a traditional test example followed by how it can be replaced with AutoFixture.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Regular Test
&lt;/h2&gt;

&lt;p&gt;Let's start with a traditional test. In the example below, it demonstrates setting up a customer with fake dummy data. Then the &lt;code&gt;CustomerService&lt;/code&gt; is used to save this customer to some data store. This may be a contrived example, but it demonstrates how much time it can take to stub fake data such as this. &lt;/p&gt;

&lt;p&gt;Also, note that a &lt;code&gt;Customer&lt;/code&gt; in this example has an &lt;code&gt;Address&lt;/code&gt; which is another entity that needs to be stubbed. &lt;/p&gt;

&lt;p&gt;Libraries do exist to assist in generating fake data such as &lt;a href="https://github.com/bchavez/Bogus" rel="noopener noreferrer"&gt;Bogus&lt;/a&gt;. But still one has to write a few lines of code.&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;CustomerTests&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&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;void&lt;/span&gt; &lt;span class="nf"&gt;AddCustomer_When_valid_customer_should_save_successfully&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// arrange&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customer&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;Customer&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Paula"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"McKinney"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;EmailAddress&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"paula_mckinney@fakeemail.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;DateOfBirth&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddYears&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;Address&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;Address&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;AddressLine1&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"4989 Wayside Lane"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;AddressLine2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hayward"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;ZipOrPostcode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"94541"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="n"&gt;Country&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"United States"&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="c1"&gt;// act&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customerService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CustomerService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;customerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddCustomer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// assert&lt;/span&gt;
        &lt;span class="c1"&gt;// make assertions here.&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;
  
  
  Using Autofixture
&lt;/h3&gt;

&lt;p&gt;Let's take the example above and replace it with AutoFixture. To start using AutoFixture, simply add the nuget package&lt;/p&gt;

&lt;p&gt;via package manager in Visual Studio&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Install-Package AutoFixture
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;via dotnet CLI&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package AutoFixture
&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;void&lt;/span&gt; &lt;span class="nf"&gt;AddCustomer_When_valid_customer_should_save_successfully_with_autofixture&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// arrange&lt;/span&gt;
    &lt;span class="kt"&gt;var&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="nf"&gt;Fixture&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;customer&lt;/span&gt; &lt;span class="p"&gt;=&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;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// act&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customerService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CustomerService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;customerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddCustomer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// assert&lt;/span&gt;
    &lt;span class="c1"&gt;// make assertions here.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hopefully, you can see that it just takes two lines of code from AutoFixture. Wait. What!? For real? Yes, for real. Just two lines of code. Here are the two lines again:&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;fixture&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Fixture&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;customer&lt;/span&gt; &lt;span class="p"&gt;=&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;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AutoFixture does all the work and just to prove it, here's a screenshot of debugging the test and inspecting the &lt;code&gt;customer&lt;/code&gt; object. &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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fe1wshcapstva2um4fx70.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fe1wshcapstva2um4fx70.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will see that AutoFixture has pre-populated all the fields with dummy data. It has also taken the initiative of stubbing the &lt;code&gt;Address&lt;/code&gt; entity as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Autofixture Customisations
&lt;/h3&gt;

&lt;p&gt;What if we want to control some of the behaviour of AutoFixture? Take, for example, the customer's date of birth. What if we wanted to set a specific date of birth for the customer as I may want to test some business logic around the date of birth?&lt;/p&gt;

&lt;p&gt;To achieve this, you can use the &lt;code&gt;With&lt;/code&gt; method to override a particular property.&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;fixture&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Fixture&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;customer&lt;/span&gt; &lt;span class="p"&gt;=&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;Build&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;With&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateOfBirth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddYears&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;30&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will set the &lt;code&gt;DateOfBirth&lt;/code&gt; to 10 years in the past.&lt;/p&gt;

&lt;p&gt;You can also ignore or disable some properties that you do not want AutoFixture to populate. For instance, the example below will ignore the &lt;code&gt;Address&lt;/code&gt; property.&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;customer&lt;/span&gt; &lt;span class="p"&gt;=&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;Build&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Without&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using AutoData
&lt;/h3&gt;

&lt;p&gt;You can take it one step further and use the &lt;code&gt;AutoData&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;Be sure to add the nuget package.&lt;/p&gt;

&lt;p&gt;via package manager in Visual Studio&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Install-Package AutoFixture.Xunit2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;via dotnet CLI&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package AutoFixture.Xunit2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;XUnit example&lt;/strong&gt;&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;Theory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AutoData&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;void&lt;/span&gt; &lt;span class="nf"&gt;AddCustomer_When_valid_customer_should_save_successfully_with_autofixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// act&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customerService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CustomerService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;customerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddCustomer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// assert&lt;/span&gt;
    &lt;span class="c1"&gt;// make assertions here.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NUnit example&lt;/strong&gt;&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;Test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AutoData&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;void&lt;/span&gt; &lt;span class="nf"&gt;AddCustomer_When_valid_customer_should_save_successfully_with_autofixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Customer&lt;/span&gt; &lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// act&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;customerService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CustomerService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;customerService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddCustomer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// assert&lt;/span&gt;
    &lt;span class="c1"&gt;// make assertions here.&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see from both XUnit and NUnit examples above, the &lt;code&gt;Customer&lt;/code&gt; is passed as a parameter in the method. There was no need to use the &lt;code&gt;var fixture = new Fixture();&lt;/code&gt; as you have seen from the earlier examples.&lt;/p&gt;

&lt;p&gt;This way of testing can be very useful, as well as saving considerable amount of time coding stub and fake data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;As you can see, with the introduction of AutoFixture, it can significantly reduce writing test data for the arrangement part of tests and also reduce the amount of code. With less code, less maintenance.&lt;/p&gt;

&lt;p&gt;For further examples, checkout &lt;a href="https://github.com/AutoFixture/AutoFixture/wiki/Cheat-Sheet" rel="noopener noreferrer"&gt;AutoFixture's cheat sheet&lt;/a&gt; and also the &lt;a href="https://github.com/AutoFixture/AutoFixture" rel="noopener noreferrer"&gt;AutoFixture&lt;/a&gt; GitHub page.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>testing</category>
      <category>csharp</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Docker for beginners - docker file, docker build, docker run, docker compose, what does it all mean?</title>
      <dc:creator>Chuen Lee</dc:creator>
      <pubDate>Tue, 27 Aug 2019 10:52:51 +0000</pubDate>
      <link>https://dev.to/ch_lee/docker-for-beginners-docker-file-docker-build-docker-run-docker-compose-what-does-it-all-mean-22oj</link>
      <guid>https://dev.to/ch_lee/docker-for-beginners-docker-file-docker-build-docker-run-docker-compose-what-does-it-all-mean-22oj</guid>
      <description>&lt;p&gt;In my &lt;a href="https://dev.to/ch_lee99/getting-started-with-docker-for-c-developers-45hc"&gt;previous post&lt;/a&gt;, I talked about my learnings of getting started with Docker in Visual studio and a brief intro into the Docker ecosystem.&lt;/p&gt;

&lt;p&gt;Visual Studio can get you up and running very fast with Docker, without having to create Docker files and using the Docker command lines. However, I am going to try and explain what a Docker file is, Docker build, Docker run and also Docker Compose and how it all comes together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tl;dr:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker files describe how to build a Docker image.&lt;/li&gt;
&lt;li&gt;The Docker build command builds images based on Docker files&lt;/li&gt;
&lt;li&gt;The Docker run command starts a Docker image&lt;/li&gt;
&lt;li&gt;Docker compose files combine docker building and running in a single file.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  So...What is a Docker file?
&lt;/h2&gt;

&lt;p&gt;A Docker file is in the form of a YAML file that contains a set of instructions that describes what the application needs in order to build it. If you are new to YAML, &lt;a href="https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html" rel="noopener noreferrer"&gt;here's a nice intro&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Taking the sample docker file from &lt;a href="https://github.com/ch-lee/DockerAspNetCoreDemo/blob/master/DockerAspNetCoreDemo/Dockerfile" rel="noopener noreferrer"&gt;this sample&lt;/a&gt; which was generated by Visual Studio, it can be broken into 4 stages.&lt;/p&gt;

&lt;p&gt;Let's try and break it down.&lt;/p&gt;

&lt;h4&gt;
  
  
  Stage 1: Specify the runtime
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base&lt;/span&gt;
&lt;span class="s"&gt;WORKDIR /app&lt;/span&gt;
&lt;span class="s"&gt;EXPOSE &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first line uses the &lt;a href="https://docs.docker.com/engine/reference/builder/#from" rel="noopener noreferrer"&gt;FROM&lt;/a&gt; syntax to define what base docker image to use. In this case, it specifies the dotnet 2.1 runtime.&lt;/p&gt;

&lt;p&gt;The next line uses the &lt;a href="https://docs.docker.com/engine/reference/builder/#workdir" rel="noopener noreferrer"&gt;&lt;code&gt;WORKDIR&lt;/code&gt;&lt;/a&gt; command which sets the working directory.&lt;/p&gt;

&lt;p&gt;The final line of the first step uses the &lt;a href="https://docs.docker.com/engine/reference/builder/#expose" rel="noopener noreferrer"&gt;&lt;code&gt;EXPOSE&lt;/code&gt;&lt;/a&gt; feature which exposes port 80.&lt;/p&gt;

&lt;h4&gt;
  
  
  Stage 2: Building
&lt;/h4&gt;

&lt;p&gt;The next stage is more involved.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;FROM microsoft/dotnet:2.1-sdk AS build&lt;/span&gt;
&lt;span class="s"&gt;WORKDIR /src&lt;/span&gt;
&lt;span class="s"&gt;COPY DockerAspNetCoreDemo/DockerAspNetCoreDemo.csproj DockerAspNetCoreDemo/&lt;/span&gt;
&lt;span class="s"&gt;RUN dotnet restore DockerAspNetCoreDemo/DockerAspNetCoreDemo.csproj&lt;/span&gt;
&lt;span class="s"&gt;COPY . .&lt;/span&gt;
&lt;span class="s"&gt;WORKDIR /src/DockerAspNetCoreDemo&lt;/span&gt;
&lt;span class="s"&gt;RUN dotnet build DockerAspNetCoreDemo.csproj -c Release -o /app&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similar to the first stage, it again uses the &lt;code&gt;FROM&lt;/code&gt; syntax to define an image. Notice this time it specifies the dotnet 2.1 sdk rather than the runtime. This is so that it can build the app.&lt;/p&gt;

&lt;p&gt;The next line sets the working directory to &lt;code&gt;src&lt;/code&gt;. It then uses the &lt;a href="https://docs.docker.com/engine/reference/builder/#copy" rel="noopener noreferrer"&gt;copy&lt;/a&gt; syntax to copy the csproj file into a new folder within docker called &lt;code&gt;DockerAspNetCoreDemo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It runs &lt;code&gt;dotnet restore&lt;/code&gt; using the copied proj file. It then copies everything and from the current source folder to the docker folder of &lt;code&gt;src&lt;/code&gt;. Finally, it runs &lt;code&gt;dotnet build&lt;/code&gt; with the release parameter and outputs the files into the &lt;code&gt;app&lt;/code&gt; directory which was created in stage 1.&lt;/p&gt;

&lt;h4&gt;
  
  
  Stage 3: Publishing
&lt;/h4&gt;

&lt;p&gt;The penultimate step below executes the &lt;code&gt;dotnet publish&lt;/code&gt; command and has a parameter that specifies the output to the &lt;code&gt;app&lt;/code&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM build AS publish
RUN dotnet publish DockerAspNetCoreDemo.csproj -c Release -o /app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Stage 4: Setting the entry point
&lt;/h4&gt;

&lt;p&gt;Finally, these steps instruct Docker where the entry point of how to start the application. I suppose it's equivalent to the &lt;code&gt;dotnet-run&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;FROM base AS final&lt;/span&gt;
&lt;span class="s"&gt;WORKDIR /app&lt;/span&gt;
&lt;span class="s"&gt;COPY --from=publish /app .&lt;/span&gt;
&lt;span class="s"&gt;ENTRYPOINT ["dotnet", "DockerAspNetCoreDemo.dll"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Docker build
&lt;/h2&gt;

&lt;p&gt;Now that we have a Docker file, one can run the &lt;code&gt;docker build&lt;/code&gt; command to build a docker image.&lt;/p&gt;

&lt;p&gt;Now, if navigate to the root directory of the demo application and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build DockerAspNetCoreDemo &lt;span class="nt"&gt;-f&lt;/span&gt; DockerAspNetCoreDemo/Dockerfile &lt;span class="nt"&gt;-t&lt;/span&gt; aspnetdemo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may get an error like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;C:&lt;span class="se"&gt;\U&lt;/span&gt;sers&lt;span class="se"&gt;\c&lt;/span&gt;hlee&lt;span class="se"&gt;\D&lt;/span&gt;ocuments&lt;span class="se"&gt;\G&lt;/span&gt;ithub&lt;span class="se"&gt;\D&lt;/span&gt;ockerAspNetCoreDemo&amp;gt;docker build DockerAspNetCoreDemo &lt;span class="nt"&gt;-f&lt;/span&gt; DockerAspNetCoreDemo/Dockerfile &lt;span class="nt"&gt;-t&lt;/span&gt; aspnetdemo
Sending build context to Docker daemon  4.209MB
Step 1/16 : FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; f8297fe48f0c
Step 2/16 : WORKDIR /app
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Using cache
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; c16c3d21ce14
Step 3/16 : EXPOSE 80
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Using cache
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 6fd93b472bcc
Step 4/16 : FROM microsoft/dotnet:2.1-sdk AS build
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; f4bc69f831aa
Step 5/16 : WORKDIR /src
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Using cache
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 782546a1fbc5
Step 6/16 : COPY DockerAspNetCoreDemo/DockerAspNetCoreDemo.csproj DockerAspNetCoreDemo/
COPY failed: GetFileAttributesEx &lt;span class="se"&gt;\\&lt;/span&gt;?&lt;span class="se"&gt;\C&lt;/span&gt;:&lt;span class="se"&gt;\W&lt;/span&gt;INDOWS&lt;span class="se"&gt;\T&lt;/span&gt;EMP&lt;span class="se"&gt;\d&lt;/span&gt;ocker-builder185318480&lt;span class="se"&gt;\D&lt;/span&gt;ockerAspNetCoreDemo&lt;span class="se"&gt;\D&lt;/span&gt;ockerAspNetCoreDemo.csproj: The system cannot find the path specified.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not great. Why? Well after some research and discovering this &lt;a href="https://github.com/moby/moby/issues/34893#issuecomment-330930534" rel="noopener noreferrer"&gt;git issue comment&lt;/a&gt; it turns out that its the way Visual Studio generates the docker file. However, running this in Visual Studio will have no issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Simpler Docker file
&lt;/h3&gt;

&lt;p&gt;With the above docker file specific to Visual Studio, below is a simpler version. This was taken and modified from the &lt;a href="https://docs.docker.com/engine/examples/dotnetcore/" rel="noopener noreferrer"&gt;docker site&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;FROM microsoft/dotnet:2.1-sdk AS build-env&lt;/span&gt;
&lt;span class="s"&gt;WORKDIR /app&lt;/span&gt;
&lt;span class="s"&gt;EXPOSE &lt;/span&gt;&lt;span class="m"&gt;80&lt;/span&gt;

&lt;span class="c1"&gt;# Copy csproj and restore as distinct layers&lt;/span&gt;
&lt;span class="s"&gt;COPY *.csproj ./&lt;/span&gt;
&lt;span class="s"&gt;RUN dotnet restore&lt;/span&gt;

&lt;span class="c1"&gt;# Copy everything else and build&lt;/span&gt;
&lt;span class="s"&gt;COPY . ./&lt;/span&gt;
&lt;span class="s"&gt;RUN dotnet publish -c Release -o out&lt;/span&gt;

&lt;span class="c1"&gt;# Build runtime image&lt;/span&gt;
&lt;span class="s"&gt;FROM microsoft/dotnet:2.1-aspnetcore-runtime&lt;/span&gt;
&lt;span class="s"&gt;WORKDIR /app&lt;/span&gt;
&lt;span class="s"&gt;COPY --from=build-env /app/out .&lt;/span&gt;
&lt;span class="s"&gt;ENTRYPOINT ["dotnet", "DockerAspNetCoreDemo.dll"]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build DockerAspNetCoreDemo &lt;span class="nt"&gt;-f&lt;/span&gt; DockerAspNetCoreDemo/Dockerfile-alternative &lt;span class="nt"&gt;-t&lt;/span&gt; aspnetdemo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-f&lt;/code&gt; is the filename of the new simpler docker file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-t&lt;/code&gt; specifies a tag for the image, in our case its &lt;code&gt;aspnetdemo&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then the output will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;C:&lt;span class="se"&gt;\U&lt;/span&gt;sers&lt;span class="se"&gt;\c&lt;/span&gt;hlee&lt;span class="se"&gt;\D&lt;/span&gt;ocuments&lt;span class="se"&gt;\G&lt;/span&gt;ithub&lt;span class="se"&gt;\D&lt;/span&gt;ockerAspNetCoreDemo&amp;gt;docker build DockerAspNetCoreDemo &lt;span class="nt"&gt;-f&lt;/span&gt; DockerAspNetCoreDemo/Dockerfile-alternative &lt;span class="nt"&gt;-t&lt;/span&gt; aspnetdemo
Sending build context to Docker daemon  4.209MB
Step 1/11 : FROM microsoft/dotnet:2.1-sdk AS build-env
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; f4bc69f831aa
Step 2/11 : WORKDIR /app
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Using cache
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 9025461ed217
Step 3/11 : EXPOSE 80
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Using cache
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 0e3c072cc161
Step 4/11 : COPY &lt;span class="k"&gt;*&lt;/span&gt;.csproj ./
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Using cache
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 3eadd1126142
Step 5/11 : RUN dotnet restore
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Using cache
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 481f505ae094
Step 6/11 : COPY &lt;span class="nb"&gt;.&lt;/span&gt; ./
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Using cache
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 570fb6690fb4
Step 7/11 : RUN dotnet publish &lt;span class="nt"&gt;-c&lt;/span&gt; Release &lt;span class="nt"&gt;-o&lt;/span&gt; out
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Using cache
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 382bad5ea05e
Step 8/11 : FROM microsoft/dotnet:2.1-aspnetcore-runtime
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; f8297fe48f0c
Step 9/11 : WORKDIR /app
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Using cache
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; c16c3d21ce14
Step 10/11 : COPY &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;build-env /app/out &lt;span class="nb"&gt;.&lt;/span&gt;
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Using cache
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 07c15508103a
Step 11/11 : ENTRYPOINT dotnet DockerAspNetCoreDemo.dll
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Using cache
 &lt;span class="nt"&gt;---&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 0eeff78b4f71
Successfully built 0eeff78b4f71
Successfully tagged aspnetdemo:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should have created a docker image, and to confirm this, you can run &lt;code&gt;docker images&lt;/code&gt; to list all the images.&lt;/p&gt;

&lt;p&gt;You should get something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;REPOSITORY          TAG                      IMAGE ID            CREATED             SIZE
aspnetdemo          latest                   0eeff78b4f71        18 minutes ago      506MB
microsoft/dotnet    2.1-aspnetcore-runtime   f8297fe48f0c        45 hours ago        503MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Docker run
&lt;/h2&gt;

&lt;p&gt;Now that we have an image, we can run the &lt;code&gt;docker run&lt;/code&gt; command to start the image and load it into a container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:80 &lt;span class="nt"&gt;--name&lt;/span&gt; aspnetapp aspnetdemo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The docker run parameters used can be described below: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt; specifies it's in detach mode, which means it will run in the background.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-p&lt;/code&gt; specifies the external port 8080 and the internal port of the image which is 80&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--name&lt;/code&gt; specifies the name of the container&lt;/li&gt;
&lt;li&gt;last parameter, &lt;code&gt;aspnetdemo&lt;/code&gt; is the image name that we want to run.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run the command &lt;code&gt;docker ps&lt;/code&gt; to verify it is running. You should see something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
5a04e20efb39        aspnetdemo          &lt;span class="s2"&gt;"dotnet DockerAspN..."&lt;/span&gt;   38 seconds ago      Up 34 seconds       0.0.0.0:8080-&amp;gt;80/tcp   aspnetapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, if you load in a browser &lt;code&gt;https://localhost:8080&lt;/code&gt; you should see something like this:&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ft02hd8of48rheuv5mr2a.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ft02hd8of48rheuv5mr2a.png" alt="docker-aspnetdemo-localhost"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Docker Compose?
&lt;/h2&gt;

&lt;p&gt;Docker compose is another command where it can be used in conjunction with Docker files. A Docker compose file will tend to have instructions on how to start the application. In general, it will just refer to the Docker file or an existing docker image and also include any app-specific parameters. For instance, in a web app, we can specify ports and any environment variables. &lt;/p&gt;

&lt;p&gt;Here is an example of a docker-compose file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.4'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;dockeraspnetcoredemo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
      &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DockerAspNetCoreDemo/Dockerfile&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:80"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that it specifies the docker file &lt;code&gt;DockerAspNetCoreDemo/Dockerfile&lt;/code&gt;. If we wanted to specify an image, the compose file will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.4'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;dockeraspnetcoredemo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aspnetdemo&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:80"&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if we run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.yml up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-f&lt;/code&gt; specifies the filename&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;up&lt;/code&gt; is the command to "start" the image&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-d&lt;/code&gt; is the detach mode which runs it in the background&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should see the demo site again if you navigate to &lt;code&gt;https://localhost:8080&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;I talked about what is a Docker file is, how to build a docker image from a docker file. Then I walked through how to start a docker image either via the docker run command or via a docker compose file.&lt;/p&gt;

&lt;p&gt;I hope this has been helpful and some insight into the Docker world.&lt;/p&gt;

&lt;p&gt;You can grab the code from &lt;a href="https://github.com/ch-lee/DockerAspNetCoreDemo" rel="noopener noreferrer"&gt;https://github.com/ch-lee/DockerAspNetCoreDemo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>dotnet</category>
      <category>dotnetcore</category>
    </item>
    <item>
      <title>Getting started with Docker for C# developers</title>
      <dc:creator>Chuen Lee</dc:creator>
      <pubDate>Tue, 06 Aug 2019 10:45:55 +0000</pubDate>
      <link>https://dev.to/ch_lee/getting-started-with-docker-for-c-developers-45hc</link>
      <guid>https://dev.to/ch_lee/getting-started-with-docker-for-c-developers-45hc</guid>
      <description>&lt;p&gt;Docker has come a long way since I first came across it in 2015, and now that Microsoft have lot's of support and with the addition of in-built docker tools in Visual Studio, I thought it was time for me to pick up it up.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Docker in simple terms?
&lt;/h2&gt;

&lt;p&gt;My interpretation of Docker in a nutshell is: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker is a tool that allows you to build, package and deploy your applications&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The statement can be rather vague as there are many tools out there that can achieve the same thing. The difference is that Docker provides a platform where you can package an application such as WordPress, MySQL, Redis, or almost any application (within reason and depending on the application) into whats called an &lt;em&gt;image&lt;/em&gt;. You can kind of think it like an iso image, or a zip file as an analogy. You can then transfer this image to another machine, which also is running Docker. Then you can use the &lt;em&gt;host&lt;/em&gt; machine to execute or start the image which will in turn start the application, and Docker will run it in whats called a &lt;em&gt;container&lt;/em&gt;. That's the gist of it really.&lt;/p&gt;

&lt;p&gt;You do not necessarily have to create a Docker image. There are many Docker images that exist and have been packaged already, many which are hosted on &lt;a href="https://hub.docker.com/"&gt;Docker hub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I suppose Docker can be broken down into two areas: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The packaging of an application into a docker image. This is referred to as "dockerizing an application".&lt;/li&gt;
&lt;li&gt; Deploying and running the dockerized application, that is, running the docker image in a container.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The easiest way to absorb this is to perhaps start with demonstration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Docker for Windows
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisite:
&lt;/h3&gt;

&lt;p&gt;You will need &lt;strong&gt;Windows 10 Pro&lt;/strong&gt;, &lt;strong&gt;Enterprise&lt;/strong&gt; or &lt;strong&gt;Education&lt;/strong&gt; - As stated in the &lt;a href="https://docs.docker.com/docker-for-windows/install/#what-to-know-before-you-install"&gt;what you need to know before you install Docker&lt;/a&gt;, it requires Microsoft Hyper-V to run. Fortunately, Windows 10 Pro, Enterprise and Education have this enabled. If you have Windows 10 Home, you will unfortunately have to find alternatives.&lt;/p&gt;

&lt;p&gt;To check if you have Hyper-V installed, Windows Task Manager will have this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dup39_4q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/n8t8t9mygwb4qwib8z7q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dup39_4q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/n8t8t9mygwb4qwib8z7q.png" alt="windows10-task-manager-virtualization-enabled"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side note&lt;/strong&gt;: I  have a Macbook Pro (2015 model) running Boot Camp with Windows, and upon installing Docker, I ran into an issue where it was complaining about virtualization. The error message was "Hardware assisted virtualization and data execution protection must be enabled in the BIOS." What the biscuit? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--F9RMHp3c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jpck4w7d2vxkqthtkn63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--F9RMHp3c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/jpck4w7d2vxkqthtkn63.png" alt="docker error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A bit of Googling I discovered that you need to boot back into Mac OS, and then restart back into Windows, and tada, it's virtualization is enabled.👍 &lt;/p&gt;

&lt;p&gt;For any troubleshooting, you can visit &lt;a href="https://github.com/docker/for-win/issues"&gt;the Docker For Windows Github Issues&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Download and Install
&lt;/h3&gt;

&lt;p&gt;Download Docker from the &lt;a href="https://store.docker.com/editions/community/docker-ce-desktop-windows"&gt;Docker Store&lt;/a&gt; for free. At the time of writing there are two versions, Docker CE (Community Edition) and Docker EE (Enterprise Edition). Docker EE provides commercial support and certified containers. Docker CE is the free version 🙂 and the one we need.&lt;/p&gt;

&lt;p&gt;Once installed, Docker will be running in the background and can be found in the Windows task tray and you should have something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ahWyJmGX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8kx19237ozaljvcg2xlj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ahWyJmGX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/8kx19237ozaljvcg2xlj.png" alt="docker version"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure the C: drive is enabled as shown:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ng6cDL0o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3lu3p6wr8yv6bdqikreq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ng6cDL0o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/3lu3p6wr8yv6bdqikreq.png" alt="docker shared drives"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, in the Advanced menu, you can tailor the desired computing resources:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FzfcjQyL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kkiioike08fr5atpf7gz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FzfcjQyL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/kkiioike08fr5atpf7gz.png" alt="docker-computing-resources"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dockerize an ASP.NET Core application
&lt;/h2&gt;

&lt;p&gt;I'm using Visual Studio 2017 Community Edition 15.3, but all you need is a Visual Studio version where Docker Tools is installed.&lt;/p&gt;

&lt;p&gt;Make sure you are running in Administrator mode.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a new ASP.NET Core project
&lt;/h3&gt;

&lt;p&gt;Create a new ASP.NET Core project in Visual Studio, and give it a suitable name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fF2oidF---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/yi6yfgggej9ybnzl56cl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fF2oidF---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/yi6yfgggej9ybnzl56cl.png" alt="docker demo visual studio project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the next screen, make sure you..&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select "Enable Docker support"&lt;/li&gt;
&lt;li&gt;Select the relevant OS where Docker containers have been set to. I have selected "Linux".&lt;/li&gt;
&lt;li&gt;Do not select "Configure HTTPS" - it keeps things simple for now.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4LhU46X7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/roeo5rxggc0kvgogrfp6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4LhU46X7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/roeo5rxggc0kvgogrfp6.png" alt="docker-demo-enable-docker-support"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visual Studio will then create two projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An ASP.NET Core web project, which includes a Docker file.&lt;/li&gt;
&lt;li&gt;A Docker Compose project which instructs Visual Studio how to start the project in a docker container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oboFPwfD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/stu8ss5tvzaplqxww0ag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oboFPwfD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/stu8ss5tvzaplqxww0ag.png" alt="docker demo solution view"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure the docker-compose project is marked as the startup project. To do this, just right-click on the project and select "Set as Startup Project".&lt;/p&gt;

&lt;p&gt;Start the project by pressing F5 or Debug &amp;gt; Start Debugging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side-note&lt;/strong&gt;&lt;br&gt;
You may get an error such as:&lt;br&gt;
&lt;code&gt;'The DOCKER_REGISTRY variable is not set. Defaulting to a blank string.'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If so, restart Visual Studio in Administrator mode.&lt;/p&gt;

&lt;p&gt;Great! You now have a standard sample ASP.NET Core web site running in a docker container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; You can run your application in docker mode or standard IIS mode. Simply set the web project as the start-up project in order to run in IIS mode, and set the docker-compose project as the startup project in order to run in docker mode.&lt;/p&gt;
&lt;h2&gt;
  
  
  How can I tell if Docker is actually running?
&lt;/h2&gt;

&lt;p&gt;You can verify this by launching command prompt or terminal of your choice, and typing:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker ps&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The result will be something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;CONTAINER ID        IMAGE                      COMMAND               CREATED             STATUS              PORTS                   NAMES
8b49df34dd03        dockeraspnetcoredemo:dev   &lt;span class="s2"&gt;"tail -f /dev/null"&lt;/span&gt;   4 hours ago         Up 4 hours          0.0.0.0:32769-&amp;gt;80/tcp   dockercompose8900117491649835616_dockeraspnetcoredemo_1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command lists running containers and verifies that the ASP.NET application is running in a docker container.&lt;/p&gt;

&lt;p&gt;The amazing thing is that breakpoints work as usual in Visual Studio and you can step into your code just like before!&lt;/p&gt;

&lt;p&gt;You can checkout the code sample in github:&lt;br&gt;
&lt;a href="https://github.com/ch-lee/DockerAspNetCoreDemo"&gt;https://github.com/ch-lee/DockerAspNetCoreDemo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>docker</category>
      <category>dotnet</category>
      <category>dotnetcore</category>
    </item>
  </channel>
</rss>
