Showing posts with label TDD. Show all posts
Showing posts with label TDD. Show all posts

Tuesday, February 25, 2014

Intro to Entity Framework Code-First

Each Monday, one member of our development team is scheduled to give a Brown Bag presentation on a technology related topic.  I was scheduled for an F# presentation in a couple weeks, but recently did some research on Entity Framework Code-First.  I was impressed with the Code-First approach as it did not have all of the overhead of an edmx and just seemed a lot cleaner.  So, instead of stumbling through an F# presentation in a couple weeks, I decided to just give a quick demo of Entity Framework Code-First today and also put it out as a blog.

I created a video that basically follows the steps below.  This will allow you to see me perform the steps just in case something is not clear in the text steps.  The audio of the video recording is not very good, but you should be able to follow along.  I will re-record it in the future, but didn't want this to stop the post from going out.  Also, please remember to change the quality to 720p by selecting Settings -> Quality -> 720p HD.







The first 17 steps are related to creating the supporting unit test project as well as a class library that the test project will call and that project makes the calls to the class library project where the Entity Framework code is located.  I encourage anyone reading this to follow all steps, but wanted to explain how this post is structured.  I will also use some ReSharper commands throughout this post, so if you do not have ReSharper, you may need to do a few of the steps manually.

1.   The first step that I always do and if you read any of my previous posts, you know that I always create a blank solution.  In this case, the blank solution name is BrownBag.  If you need a refresher on how to do this, see my post on creating a Blank Solution.

2.   Next, because we are TDD developers, we create our unit test project named BrownBag.Tests.  We do this by right clicking on the BrownBag solution and selecting Add -> New Project.  Select the Test project and name it BrownBag.Tests as seen below.
























3.   The first test method we are going to create is going to be named the following:

    public void AddUser_ValidUserName_ReturnsUserId  

4.   Inside the test method under Arrange, type the following code:

      var user = new User();

5.   As you can see, User does not exist yet, so we have to create it, but where is it going to go?  For the purpose of this demo, we are going to create a new Class Library project named BrownBag.BL and add our code there.

6.   After the new project is created, rename the Class1.cs file to User.cs

7.  Go back to your test project and place your cursor over User() and then select Alt + Enter.  You will see an option for Reference 'BrownBag.BL and use BrownBag.BL.User.  This will add the correct using directive and add the reference as well.
























8.  You are now ready to "Act" within your test method by typing the following code:

     var userId = user.Create(userDTO);

9.   As you can see we will need to add the "Create" method within our User class that is defined in the       BrownBag.BL Class Library project.  To accomplish this easily, put your cursor over the Create method call and select Alt + Enter.  This will give you the option to create the method User.Create.










10.  You will see that the Create method is created for you.  Our test will expect the return value to be an int, so we need to change object to int and replace the NotImplementedException with return 0; 













11.   If we go back to our test class, we will see that the passed in parameter is not defined.  In our example, we want to create a DTO that will be passed in to the Create method.  To do this, you might have guessed, you need to put your mouse over userDTO and select Alt + Enter.  This will create a local variable within our Act section, so we need to move it to the Arrange section.  To do this quickly and since we are on the line we want to move, we select Ctrl + X, then move our cursor to after the creation of user and then select Ctrl + V.






















12.  Replace the code that we moved with the following:

     var userDTO = new UserDTO
     {
         UserName = "UnitTest_" + Guid.NewGuid().ToString()
     };  

13.  Click UserDTO, then Alt + Enter, then Create Class UserDTO.  This will create the DTO class that will be used to pass in to the Create method.












14.  Click UserName, then Alt + Enter, then Create Property UserName.  This created the property UserName without having to write any code.










15.  Move cursor to the right of UserDTO and select F6, then select Move To Folder.  Change the target folder to the BrownBag.BL.  We do this to move the created class to a new file in a better location.























16.  Within the Create method of the User class, change the passed in userDTO type from object to UserDTO.

17.  We are now ready to create our Assert by entering the following code into our Assert section in our test method.

       Assert.IsTrue(userId > 0);

Now that we have our test complete, we can get into our Entity Framework specific code!

18.  Add a new Class library project to our solution that will be used for our Datalayer and name it BrownBag.DL.  Once the project is created, delete Class1.cs.

19.  In order to use the entity framework, you must add a reference to the EntityFramework assembly.  We are going to use the Package Manager Console and install a NuGet package.  To open the Package Manager Console, go to Tools -> Library Package Manager -> Package Manager Console.  














Once there, change the default project to BrownBag.DL, 





and then type in the following:

PM> Install-Package EntityFramework

If everything was successful, you will see the assemblies added as seen below:










Do the same steps for BrownBag.BL and BrownBag.Tests projects by changing the Default project and running the same command.

20.  Add a class to your BrownBag.DL named BrownBagContext.cs and then add a constructor like the following and make sure your class inherits from DbContext













21.  Add the following connection strings section to the App.config in the DL and Tests project.  In the below example, please replace the Data Source with your values and also make sure a blank database with the catalog name is created in your SQL Server instance.  We create the Database here, but the columns will be created using Code-First.

<connectionStrings>
<add name="BrownBagContext" connectionString="Data Source=XXXX\SQLEXPRESS;initial catalog=BrownBag;persist security info=True;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
</connectionStrings>

22.  Add the following property to your BrownBagContext.cs class

       public DbSet<User> Users { get; set; }

23.   Put your cursor over User, select Alt + Enter,  and select Create class 'User'.  This will create the class that will be used to create the columns in our database.

















24.  Put your cursor next to User and select F6, and then Move to Another File.  This will put the class in a new file.










25.  Add the following properties to your new class:

     [Key]
     [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
     public int UserId { get; set; }
     [StringLength(50)]
     public string UserName { get; set; }

26.   Add the two using directives

     using System.ComponentModel.DataAnnotations;
     using System.ComponentModel.DataAnnotations.Schema;

27.   Add a reference and using directive to BrownBag.DL in BrownBag.BL.

28.   Add the following code to the Create method in the User Class in the BL

       using (var dbContext = new BrownBag.DL.BrownBagContext())
     {
        var user = new BrownBag.DL.User
        {
           UserName = userDTO.UserName
        };

        dbContext.Users.Add(user);
        dbContext.SaveChanges();

        return user.UserId;
     }

29.  Finally, we can use migrations to create the table and columns in our database.  Go back to the Package Manager Console and type Enable-Migrations.  You will see a Migrations folder created within your project with a class named Configuration.

30.  When the Enable-Migrations command is complete and successful, type Add-Migration UserTableCreation.  The Add-Migration command will create a class that will be executed to create the table and columns in the database.  The UserTableCreation is a label that you make up to identify the migration.

31.  You will now see that the Migrations folder contains the C# code that we explained above.  










At this point the table is not created yet.  To create the table in your database, type the following in the Package Manager Console:

PM> Update-Database

32.  If all goes well, you should see the table is created along with the fields you specified.













33.  Now, go back to your unit test, set a breakpoint and step through your code.  You should get a userId back which should make your test pass!  You should also go to the database and verify that a record was created.












That is my quick intro to Entity Framework Code-First.  There are many posts online that explain some of this, but I think this pulls a lot together that may be assumed from other sites.  I hope you enjoyed and learned something along the way.  If you go through the steps and something does not make sense, please take a look at the video.  As I said above, the audio quality is not very good, but you should be able to follow along.

peace yo!

Thursday, November 21, 2013

TDD Controller creation from unit test - Part 1

The dev team that I am currently on is making a huge effort to adopt TDD.  One discussion that comes up every now and then is what to do with your MVC controllers when it comes to TDD.  A couple of us say that you should still start with your test and a few say that it is just too easy to create a control without a test and starting from your test is just a waste of time.  This post is going to show you how easy it is to start with your test first and follow TDD the correct way using a few Resharper shortcuts.  These shortcuts are not required and there are other ways to accomplish the same thing, but Resharper does make it easier and quicker.

Do not be intimidated by the number of steps below.  I recorded the steps and it took less than two minutes to perform all steps.  You can see the recording of the steps in this video below.





1. The first thing that you need to do is create a blank solution and then add an ASP.NET MVC 4 Web Application and Unit Test Project.  If you don't know how to do this, you can read my my post about and it here.  When you are done, your solution should look similar to the following:





















2.  Add a Unit Test to your test project by right-clicking on your test project, then selecting Add -> Unit Test...










3.  Delete the provided TestMethod and use the Test Method Snippet that I introduced you to in my first blog post to give you the following test method stub.











4.  After the Assert comment, type the following:

     Assert.IsNotNull(homeController);

5.  With your cursor at the end of the line you just typed, type Alt-Enter and you should see something similar to the following:










6.  Select "Create local variable 'homeController'" by typing Enter






7.  Type the End Key















8.  Type Ctrl-X and move your cursor to just below the Arrange comment and type Ctrl-V to get your method to look like the following:












9.  Change object to var, type End, type Backspace, then type  = new HomeController();  You should now have the following:











10. With your cursor still positioned at the end of the line, type Alt-Enter and then select "Create class 'HomeController'"









11.  A class named HomeController will be created below your test method as seen  below.














12. Type End and then F6 to get the following menu:








13.  Select 'Move to Folder'.  This will open the Resharper Move to Folder dialogue as seen below.




















14.  Change the Target Folder to the Controllers folder in the ASP.NET MVC 4 Web Application that you created in step #1.  In my case, it is Namyaf.WEB\Controllers as seen below.









15.  Click Next and you will see your new file within the location you specified.













16.  Open HomeController.cs

17.  Make the HomeController class inherit from Controller

18.  Add the following using directive

     using System.Web.Mvc;











19.  Build the solution.  If you have errors, correct them.  If you cannot correct them, let me know and I can help.

20.  If you run your test within MSTEST or Resharper, you will see that the test passes.


Resharper test
MSTEST


















I hope you enjoyed this post and learned something.  In part two, I will be adding the controller actions and continuing with a little TDD.

peace yo!


Saturday, October 26, 2013

Test Method Snippet (Visual Studio)

If you practice Test-driven Development (TDD) you know there are many standards and patterns that you can use.  One pattern that myself and others on my team like is the Arrange, Act, and Assert pattern when writing our tests.  This pattern is included in the existing tests for you when you create a new ASP.NET MVC 4 Web Application and then select the option to Create a unit test project to it.  What I noticed is that when I use a snippet to create a new test method, the Arrange, Act, and Assert comments are not there.  This is not a big deal to most as they can remember to Arrange, Act, and Assert, but I would like the comments added to my new test methods when I use a snippet.  Along with not liking that my test methods do not have the comments, I also realized that the name of the new test method of MyTestMethod is dumb and should be changed to our naming standards which came from Roy Osherove.  The naming standard we agreed on is [UnitOfWork_StateUnderTest_ExpectedBehavior] and an explanation of this can be found at Roy's site here.  Making these changes in the snippet is simple and the steps to accomplish it are below.

1.  Open Visual Studio.

2.  Go to Tools -> Code Snippets Manager.


3.  Change the Language to Visual C# and expand the Test folder.

4.  Copy the path located in the Location.

5.  Open Windows Explorer and browse to the location copied in the previous step.

6.  Make a Copy of the testmethod.snippet. 

7.  If you want to still use the original snippet in Visual Studio, rename it by adding a prefix.  If you do not want to use the original snippet, you need to make sure it does not end in .snippet and append something to it or change it.  I prefer to keep it so others that are not aware of my new snippet can still use the old one, so I added a prefix of "Orig_".


8.  Open testmethod.snippet in notepad, Visual Studio or any other program that will allow you to edit text.

9.  Change the text within the Shortcut element from testm to testmm.  The reason for the second 'm' is that there are other methods that may show up from IntelliSense and adding the second m will eliminate them from showing up and the snippet will be invoked by typing testmm followed by a tab.

      old: <Shortcut>testm</Shortcut>
      new: <Shortcut>testmm</Shortcut>

10.  Change the text within the Default element from MyTestMethod to to UnitOfWork_StateUnderTest_ExpectedBehavior.

      old: <Default>MyTestMethod</Default> 
      new: <Default>UnitOfWork_StateUnderTest_ExpectedBehavior</Default>

11.  Add the following three lines of comments to the method just before the text  $end$ within public void $name$()
         
          // Arrange          
          var x = false;
          var y = new y();
          
          // Act          
          x = y.DoStuff();
          
          // Assert          
          Assert.IsTrue(x); 


12.  Save the file.

13.  Close all instances Visual Studio if there are any open.

14.  Open a Unit Test Project within Visual Studio and set your cursor within a test class.

15.  Type testmm followed by a [tab].  As you can see, the snippet will now display the following which has our new method name and the comments to help us create good tests.





Hopefully you learned something from this post and it will help you modify or add more snippets to help you code faster and better.

peace yo!