Adding some code

It is time to implement all the classes from the preceding class diagram and look at our overall source and project structure.

Let's open Visual Studio and create a blank solution named EmployeeBeneftis.sln. In this solution, let's add a project of the Class Library type named Domain.

Tip

To add a blank solution, you need to go to File | New | Project. On the New Project dialog that opens, inside the pane on the left side, locate a tree node named Other Project Types. Inside this node, you will find an item named Visual Studio Solutions. Click on this item, and then, you can choose Blank Solution in the middle pane.

We will now add all the classes to the Domain project. In order to minimize the compilation errors, we will start with the class that does not refer to other classes. Right-click on the Domain project in Visual Studio and add a class named Address. Use the following code for the body of the class:

namespace Domain
{
  public class Address
  {
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string Postcode { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
  }
}

Tip

For the sake of brevity, I am skipping the using namespace statements from these code snippets. I intend to do so unless the mention of namespace is critical to the piece of code at hand. Other times, you should be able to proceed with whatever namespaces Visual Studio adds for you automatically.

Let's add a second class named Benefit and use the following code snippet: This class acts as a base class for any class that represents an employee benefit:

namespace Domain
{
  public class Benefit
  {
    public string Name { get; set; }
    public string Description { get; set; }
    public Employee Employee { get; set; }
  }
}

Next, we can add classes representing our three benefits. Before this, let's define the enumeration that will be used by the leave benefit as follows:

namespace Domain
{
  public enum LeaveType
  {
    Casual,
    Sick,
    Unpaid
  }
}

With the enumeration in place, here is the code snippet for our three employee benefit classes:

namespace Domain
{
  public class SkillsEnhancementAllowance : Benefit
  {
    public int RemainingEntitlement { get; set; }
    public int Entitlement { get; set; }
  }
}


namespace Domain
{
  public class SeasonTicketLoan : Benefit
  {
    public int Amount { get; set; }
    public double MonthlyInstalment { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
  }
}

namespace Domain
{
  public class Leave : Benefit
  {
    public LeaveType Type { get; set; }
    public int AvailableEntitlement { get; set; }
    public int RemainingEntitlement { get; set; }
  }
}

We have all the classes in place except the class that represents an employee. Let's add one more classes named Employee and use the following code snippet:

namespace Domain
{
  public class Employee
  {
    public string EmployeeNumber { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string EmailAddress { get; set; }
    public DateTime DateOfBirth { get; set; }
    public DateTime DateOfJoining { get; set; }

    public Address ResidentialAddress { get; set; }
    public bool IsAdmin { get; set; }
    public string Password { get; set; }
    public ICollection<Benefit> Benefits { get; set; }
  }
}

Note that we have a collection of Benefit classes in the Employee class. Not every employee may be eligible for every type of benefit. So, we cannot have an association to every benefit type in Employee. A collection of benefits helps with such a situation when you do not know in advance which benefits a particular employee is eligible for. Our code should compile at this point. If not, just fix whatever errors come up.

Next, we are going to add one more project for our unit tests. So, let's add another project of the Class Library type and name it Tests.Unit. This project needs to reference the Domain project because we will be calling into the classes defined in the Domain project from our tests. We are going to use NUnit to write our tests. So, let's go and grab NUnit by using NuGet.

Adding the NuGet packages to projects

There are two ways in which you can add NuGet packages to your projects. The first one uses the Manage NuGet Packages menu of Visual Studio. This is an easy-to-follow option in which you do not need to leave Visual Studio. The second uses the Package Manager Console feature of Visual Studio. This is slightly involved but gives you better control over the packages that you are installing. We will look at the first option here. I will leave the second option for you to explore:

  1. Right-click on the project to which you want to add a NuGet package. In our case that would be the project named Tests.Unit. You would see the following menu pop out:
    Adding the NuGet packages to projects
  2. In the above menu, click on Manage NuGet Packages… highlighted with the yellow rectangle in the preceding screenshot. This will bring out the Manage NuGet Packages dialog for the Tests.Unit project. This is how the dialog looks:
    Adding the NuGet packages to projects

    On this dialog, there is a search box in the top-right corner. We can enter here the names of the packages that we want to search.

    Tip

    The search functionality is activated as you start typing, so there is no need to hit the enter key. Rather do not hit the enter key as doing do will start installing whatever NuGet package is currently selected.

    In the left-hand pane, you can see various options. I do not intend to go into the details of these, but one thing worth noting is that nuget.org is selected. This means that we are using nuget.org as our source of NuGet packages. If you are using a different source, then you can change this from the settings, but you will rarely need to do so.

  3. Next, we enter NUnit into the search box and NUnit appears in the result list at the top:
    Adding the NuGet packages to projects
  4. Next, we click on the Install button that appears next to NUnit. This will install NUnit in our Tests.Unit project. After NUnit is successfully installed, the Manage NuGet Packages dialog changes to look as shown in the following screenshot:
    Adding the NuGet packages to projects
  5. Notice the green tick next to NUnit, which tells us that this package is installed in the Tests.Unit project.

Back to our test

If you have never used NUnit, here is a brief primer for you:

  1. Every unit test is written as a method.
  2. An attribute [Test] is added to a test method. This is how NUnit distinguishes between a test method and a normal method.
  3. Any class that has one or more test methods can optionally have an attribute [TestFixture] added to it. That is how the NUnit GUI runner (or other NUnit runners) finds all the test classes/fixtures to be run. However, with the latest versions of ReSharper, this attribute is not required.
  4. The last and the most important, an using statement to reference the NUnit.Framework namespace should be added to any class that has test methods in it.

Here is a how a test looks:

using NUnit.Framework

namespace Tests.Unit
{
  [TestFixture]
  public class EmployeeTests
  {
    [Test]
    public void EmployeeIsEntitledToPaidLeaves()
    {
      //Arrange
      var employee = new Employee();

      //Act
      employee.Leaves = new List<Leave>();
      employee.Leaves.Add(new Leave
      {
        Type = LeaveType.Paid,
        AvailableEntitlement = 15
      });

      //Assert
      var paidLeave = employee.Leaves.FirstOrDefault(l => l.Type == LeaveType.Paid);
      Assert.That(paidLeave, Is.Not.Null);
      Assert.That(paidLeave.AvailableEntitlement, Is.EqualTo(15));
    }
  }
}

This is not a meaningful test. The purpose is to show you an example of how tests are written in NUnit. Let me walk you through this test in order to understand it better. A unit test usually has three parts – Arrange, Act, and Assert. You can see these commented in the preceding test.

In the Arrange part, you set up everything that is required to run the test. In our example, we create a new instance of the Employee class.

In the Act part, we execute the code that is to be tested. In the preceding test, we add a Leave object to the Leaves collection of the Employee class. This Leave object is of the Paid type having an entitlement of 15.

In the Assert part, we verify that the code that we wanted to test has behaved correctly. In the preceding test, we verify this by finding the Leave object from the list of Leaves whose type is Paid. We confirm that such an object is present in the list and that AvailableEntitlement has a value of 15.

This was simple, wasn't it? If this is first time you are seeing tests, don't worry. We are going to see lot of these and we will get there together.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.144.108