In this tutorial, we are going to start the beginnings of a fictional CRM type application. A customer relationship management system simply keeps track of customers and their related data. We’ll use Visual Studio to build out a new Customer class, then define the properties that we need for a customer. These will include things like the first name, last name, email address, and so on. Along the way, we’ll add a test project to our visual studio solution. In that project, we’ll create an accompanying test class for the Customer class to ensure that it works properly. Let’s get started.
Adding A New Project
To get started building our new Customer class we first need a new project in Visual Studio. We can click on File->New->Project to bring up the new class wizard.
Once there we can choose a name for the solution as well as the project. The project name is CRMBIZ and the solution is simply CRM. CRMBIZ stands for “Customer Relationship Manager Business Layer” and of course CRM simply stands for “Customer Relationship Manager”.
After all of this is taken care of, we are given a new class file to start with in the editor and solution explorer.
Building A Customer Class
Let’s rename that default class to Customer.cs and build out the class like we see below. Our goal here is to create a Class that can represent a customer in our CRM system. We can see the following members of the class.
- lastName
- LastName
- FirstName
- EmailAddress
- CustomerId
- FullName
using System;
namespace CRMBIZ
{
public class Customer
{
private string _lastName;
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
}
}
public string FirstName { get; set; }
public string EmailAddress { get; set; }
public int CustomerId { get; private set; }
public string FullName
{
get
{
return LastName + ", " + FirstName;
}
}
}
}
Build A Unit Test For The Class
We want to ensure our class is working by using a unit test. It makes sense to create a new folder to hold the unit test project. So we go ahead and right-click on the solution name, then choose Add->New Solution Folder and name it Test.
Once that is complete we can add a new test project into the new solution folder. Right click on the Test folder, then choose Add->New Project, and choose the Unit Test option.
In our case we name it CRMBIZ.Test. You can name yours whatever you like. In order for the test project to actually be able to test the code in our main project, we need to reference an assembly from the main project. This can be done by right clicking on the References node of the test project, then choosing to add the reference to the main project like we see here.
Adding Test Methods
In our new test project, we can rename the default test file to CustomerTest.cs. Our goal is to test the Customer class in the project, so the convention is to use the name of the class followed by the word Test. Testing follows the same approach for any situation.
- Set up the data
- Take an action
- Assert the results
So that is what we do below. First we set up the data by creating a new Customer object. This is an actual object derived from the class we created above.
CustomerTest.cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace CRMBIZ.Test
{
[TestClass]
public class CustomerTest
{
[TestMethod]
public void FullNameTestValid()
{
// Set up the data
Customer customer = new Customer();
customer.FirstName = "Heather";
customer.LastName = "Smith";
string expected = "Smith, Heather";
// Take an action
string actual = customer.FullName;
// Assert the results
Assert.AreEqual(expected, actual);
}
}
}
What does the code above do for us? Let’s examine. First, we create a new customer object.
Assign data into the FirstName property.
Assign data into the LastName property.
Next we set up the expected data we want to see after we access the customer.FullName property. This should return to us the last name, a comma, then a space, and finally the first name of the customer.
We are then ready to take an action. We access the FullName property and store the result in the actual
variable.
Finally, we can assert if this condition is true.
When we run the test in test explorer, it looks like it is working!
Beefing Up The FullName Getter
We can modify the getter in the Customer class for FullName now. With the updated code below, some logic is added to determine whether or not a comma is needed depending on if you have the first name only, or the last name only.
using System;
namespace CRMBIZ
{
public class Customer
{
private string _lastName;
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
}
}
public string FirstName { get; set; }
public string EmailAddress { get; set; }
public int CustomerId { get; private set; }
public string FullName
{
get
{
string fullName = LastName;
if (!string.IsNullOrWhiteSpace(FirstName))
{
if (!string.IsNullOrWhiteSpace(fullName))
{
fullName += ", ";
}
fullName += FirstName;
}
return fullName;
}
}
}
}
Now we can better test the class. We can check to see that all the properties are working as expected.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace CRMBIZ.Test
{
[TestClass]
public class CustomerTest
{
[TestMethod]
public void FullNameTestValid()
{
// Set up the data
Customer customer = new Customer();
customer.FirstName = "Heather";
customer.LastName = "Smith";
string expected = "Smith, Heather";
// Take an action
string actual = customer.FullName;
// Assert the results
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void FullNameFirstNameEmpty()
{
//-- Arrange
Customer customer = new Customer();
customer.LastName = "Smith";
string expected = "Smith";
//-- Act
string actual = customer.FullName;
//-- Assert
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void FullNameLastNameEmpty()
{
//-- Arrange
Customer customer = new Customer();
customer.FirstName = "Heather";
string expected = "Heather";
//-- Act
string actual = customer.FullName;
//-- Assert
Assert.AreEqual(expected, actual);
}
}
}
Running all tests shows that the class appears to be working great.
Objects Are Reference Types
We saw in an earlier tutorial that in C#, objects are reference types. Quickly recapping, reference types store a pointer to their data. Value types store their data directly. This is an important concept. Essentially, you can have multiple variables that point to the same data when using reference types.
Below we make use of the static
modifier on a new member of Customer, InstanceCount. The static modifier declares that a member belongs directly to the class, rather than to an object instantiated from the class. Therefore you access a static member using the class name, not the object variable.
using System;
namespace CRMBIZ
{
public class Customer
{
public static int InstanceCount { get; set; }
private string _lastName;
public string LastName
{
get
{
return _lastName;
}
set
{
_lastName = value;
}
}
public string FirstName { get; set; }
public string EmailAddress { get; set; }
public int CustomerId { get; private set; }
public string FullName
{
get
{
string fullName = LastName;
if (!string.IsNullOrWhiteSpace(FirstName))
{
if (!string.IsNullOrWhiteSpace(fullName))
{
fullName += ", ";
}
fullName += FirstName;
}
return fullName;
}
}
}
}
Testing Static Members
Let’s test the concept above out. In the updated code below we now have a test method named StaticTest()
. The test creates three new customer objects, and stores them in three different variables. Each variable references a different customer object. Notice what we are doing after each assignment of a name to the FirstName property in each customer object. We are making use of that static InstanceCount from above to increment its value each time a new object is created and assigned a value. We then assert that the reference count is three like we believe it should be.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace CRMBIZ.Test
{
[TestClass]
public class CustomerTest
{
[TestMethod]
public void FullNameTestValid()
{
// Set up the data
Customer customer = new Customer();
customer.FirstName = "Heather";
customer.LastName = "Smith";
string expected = "Smith, Heather";
// Take an action
string actual = customer.FullName;
// Assert the results
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void FullNameFirstNameEmpty()
{
// Set up the data
Customer customer = new Customer();
customer.LastName = "Smith";
string expected = "Smith";
// Take an action
string actual = customer.FullName;
// Assert the results
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void FullNameLastNameEmpty()
{
// Set up the data
Customer customer = new Customer();
customer.FirstName = "Heather";
string expected = "Heather";
// Take an action
string actual = customer.FullName;
// Assert the results
Assert.AreEqual(expected, actual);
}
[TestMethod]
public void StaticTest()
{
// Set up the data
var c1 = new Customer();
c1.FirstName = "Heather";
Customer.InstanceCount += 1;
var c2 = new Customer();
c2.FirstName = "Susan";
Customer.InstanceCount += 1;
var c3 = new Customer();
c3.FirstName = "Erica";
Customer.InstanceCount += 1;
// Take an action
// Assert the results
Assert.AreEqual(3, Customer.InstanceCount);
}
}
}
Running the suite of tests shows that things are still working quite nicely!
Creating C# Class Properties And Tests Summary
In this tutorial we used Visual Studio to create a new solution and project to get started creating a Customer class for a CRM type application. Next up we built the Customer class, which as we learned before, defines a type. Anytime you use the class keyword in C#, you are creating a type. By default, a new class added to a project in Visual Studio have no access modifier. This means that if you want to access the class from other components, you’ll need to make an adjustment and add the public
keyword to the class. We also got a feeling for test driven development in C#, as we created an accompanying test class to the Customer class named CustomerTest.
- Creating C# Class Properties And Tests – vegibit (vegibit.com)
- Classes and objects – C# Fundamentals tutorial (learn.microsoft.com)
- .net – unit testing c# properties – Stack Overflow (stackoverflow.com)
- Basics Of Creating And Using Classes In C# – C# Corner (www.c-sharpcorner.com)
- c# – Test all properties with single test function – Code (codereview.stackexchange.com)
- Properties – Unit Testing in C# – Educations Media Group (docs.educationsmediagroup.com)
- Learn How to Create Classes in C# – MUO (www.makeuseof.com)
- C# Classes and Objects – W3School (www.w3schools.com)
- Creating Instances of .NET Classes Defined in Applications (support.smartbear.com)
- c# – Stubbing Properties with private setters for tests – Software … (softwareengineering.stackexchange.com)
- Understanding Classes, Methods, and Properties in C# (www.developer.com)
- C# Programming Tutorial 62 – Creating Properties – YouTube (www.youtube.com)
- How C# Reflection Works With Code Examples – Stackify (stackify.com)
- Properties in C# with Examples – Dot Net Tutorials (dotnettutorials.net)