使用Visual Studio创建C语言类的属性和测试

163 阅读7分钟

在本教程中,我们将开始一个虚构的CRM类型的应用程序的雏形。一个客户关系管理系统可以简单地跟踪客户和他们的相关数据。我们将使用Visual Studio建立一个新的客户类,然后定义我们需要的客户属性。这些将包括诸如名字、姓氏、电子邮件地址等等。在这个过程中,我们将在我们的Visual Studio解决方案中添加一个测试项目。在该项目中,我们将为Customer类创建一个附带的测试类,以确保它能正常工作。让我们开始吧。


添加一个新项目

为了开始建立我们的新客户类,我们首先需要在Visual Studio中建立一个新项目。我们可以点击File->New->Project来调出新类的向导。
visual studio file new project

在那里,我们可以为解决方案和项目选择一个名称。项目名称是CRMBIZ,解决方案是简单的CRM。CRMBIZ代表 "客户关系管理业务层",当然,CRM只是代表 "客户关系管理"。
visual studio solution name

在所有这些都处理完毕后,我们在编辑器和解决方案资源管理器中得到了一个新的类文件来开始使用。
new class created


建立一个客户类

让我们把这个默认的类重命名为Customer.cs,然后像下面这样建立这个类。我们的目标是创建一个可以在我们的CRM系统中代表客户的类。我们可以看到该类的以下成员。

  • LastName
  • 最后一个名字
  • 电子邮件地址
  • 客户身份
  • 全名
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;
            }
        }
    }
}

为该类建立一个单元测试

我们想通过单元测试来确保我们的类在工作。创建一个新的文件夹来存放单元测试项目是有意义的。所以我们继续前进,右击解决方案的名称,然后选择添加->新的解决方案文件夹,并将其命名为测试。
visual studio add new solution folder

一旦完成,我们就可以在新的解决方案文件夹中添加一个新的测试项目。右键点击测试文件夹,然后选择添加->新项目,并选择单元测试选项。
add new project to solution visual studio

在我们的例子中,我们把它命名为CRMBIZ.Test。你可以随心所欲地命名你的项目。为了使测试项目能够真正测试主项目中的代码,我们需要引用主项目中的一个程序集。这可以通过右击测试项目的引用节点来完成,然后选择将引用添加到主项目中,就像我们在这里看到的那样。

add reference to project you want to test


添加测试方法

在我们的新测试项目中,我们可以将默认的测试文件重命名为CustomerTest.cs。我们的目标是测试项目中的Customer类,所以惯例是使用类的名称,后面跟着Test这个词。在任何情况下,测试都遵循同样的方法。

  • 设置数据
  • 采取一个行动
  • 断言结果

所以这就是我们下面要做的。首先,我们通过创建一个新的客户对象来设置数据。这是一个从我们上面创建的类派生出来的实际对象。


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);
        }
    }
}

上面的代码为我们做了什么?让我们来看看。首先,我们创建一个新的客户对象。
create new customer object


将数据分配给FirstName属性。
assign data to firstname property


将数据分配到LastName属性中。
assign data to lastname property


接下来,我们设置我们希望在访问customer.FullName属性后看到的预期数据。这应该向我们返回姓氏,一个逗号,然后是一个空格,最后是客户的名字。
the expected result


然后我们准备采取一个行动。我们访问FullName属性并将结果存储在 **actual**变量中。
take an action


最后,我们可以断言这个条件是否为真。
c sharp assert-areequal


当我们在测试资源管理器中运行该测试时,它看起来是有效的。
test explorer run all tests


加强FullName的获取器

我们现在可以修改客户类中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
            {
                string fullName = LastName;
                if (!string.IsNullOrWhiteSpace(FirstName))
                {
                    if (!string.IsNullOrWhiteSpace(fullName))
                    {
                        fullName += ", ";
                    }
                    fullName += FirstName;
                }
                return fullName;
            }
        }
    }
}

现在我们可以更好地测试这个类。我们可以检查一下所有的属性是否按预期工作。

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);
        }
    }
}

运行所有的测试表明,这个类似乎工作得很好。
tests are still passing


对象是引用类型

我们在前面的教程中看到,在C#中,对象是引用类型。快速回顾一下,引用类型存储一个指向其数据的指针。值类型则直接存储其数据。这是一个重要的概念。从本质上讲,在使用引用类型时,你可以有多个指向相同数据的变量。

下面我们使用了 static修改器在客户的一个新成员InstanceCount上。静态修饰符声明一个成员直接属于该类,而不是属于从该类实例化的对象。因此,你使用类的名称来访问静态成员,而不是使用对象变量。

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;
            }
        }
    }
}

测试静态成员

让我们测试一下上面的概念。在下面的更新代码中,我们现在有一个测试方法,名为 StaticTest().该测试创建了三个新的客户对象,并将它们存储在三个不同的变量中。每个变量引用一个不同的客户对象。注意我们在每个客户对象的FirstName属性中分配了一个名字后所做的事情。我们正在利用上面的静态InstanceCount,在每次创建新对象并赋值时增加它的值。然后我们断言引用计数为3,就像我们认为的那样。

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);
        }
    }
}

运行这套测试表明,事情仍在很好地进行着!
static instanceof class test


创建C#类属性和测试总结

在本教程中,我们使用Visual Studio创建了一个新的解决方案和项目,开始为一个CRM类型的应用程序创建一个客户类。接下来,我们建立了客户类,正如我们之前学到的,它定义了一个类型。任何时候你在C#中使用class关键字,你就在创建一个类型。默认情况下,添加到Visual Studio项目中的新类没有访问修改器。这意味着,如果你想从其他组件中访问这个类,你需要做一个调整,在类中添加 public关键字到该类中。我们还感受到了C#中的测试驱动开发,因为我们为Customer类创建了一个附带的测试类,名为CustomerTest。