如何在C#

时间:2016-01-14 20:20:13

标签: c# .net unit-testing oop

我有一个应用程序,允许您添加学生和讲师的详细信息,搜索它们,并显示它们等。这是为大学作业,我必须测试我创建的五种方法。首先,我不确定如何测试涉及字符串的方法,因为我看到的所有测试方法都涉及银行帐户应用程序,并且测试提款和存款方法似乎很简单,因为您只需要添加和减去数字。我根本不确定如何测试我的(例如)AddLecturer()方法。如果我创建的Status类输入正确,我试图获取其中一种方法来抛出异常,但程序似乎仍然认为它是一个未处理的异常。如何修复异常以便正确处理,以及如何测试其他方法?

这是使用所有方法的应用程序的主要入口点。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DBSManagement
{
    public class College: Staff
    {
        public static List<Student> students = new List<Student>();
        public static List<Lecturer> lecturers = new List<Lecturer>();

        public static void Main()
        { 
            int choice;
            bool seeAgain = true;

                do
                {
                    Console.WriteLine("Press");
                    Console.WriteLine("1: To add a student");
                    Console.WriteLine("2: To add a lecturer");
                    Console.WriteLine("3: To search for a lecturer or student");
                    Console.WriteLine("4: To show the details of all enrolled students");
                    Console.WriteLine("5: To show the names of all lecturers");
                    Console.WriteLine("6: To show payroll details for a lecturer");
                    Console.WriteLine("7: To quit");
                    int.TryParse(Console.ReadLine(), out choice);

                    switch (choice)
                    {
                        case 1:
                            AddStudent();
                            break;
                        case 2:
                            AddLecturer();
                            break;
                        case 3:
                            SearchPerson();
                            break;
                        case 4:
                            ShowStudents();
                            break;
                        case 5:
                            ShowLecturers();
                            break;
                        case 6:
                            ShowPayrollDetails();
                            break;
                        case 7:
                            seeAgain = false;
                            break;
                        default:
                            Console.WriteLine("Invalid option selected");
                            break;
                    }
                } while (seeAgain);
            }
        public static void AddStudent()
        {
            Student student = new Student();
            Console.WriteLine("Enter student name:");
            if (Console.ReadLine() != null)
            {
                student.Name = Console.ReadLine();
            }
            else throw new ArgumentNullException("Please enter a name");

            Console.WriteLine("Enter student address:");
            student.Address = Console.ReadLine();
            Console.WriteLine("Enter student phone number:");
            student.Phone = Console.ReadLine();
            Console.WriteLine("Enter student email:");
            student.Email = Console.ReadLine();
            Console.WriteLine("Enter student PPSN:");
            student.PPSN = Console.ReadLine();
            Console.WriteLine("Enter student status (postgrad or undergrad):");
            EnterStat:
                string stat = Console.ReadLine().ToLower();
                if (stat == "postgrad" || stat == "undergrad")
                {
                    student.Status = (Status)Enum.Parse(typeof(Status), stat);
                }
                else
                {
                    Console.WriteLine("Please enter either postgrad or undergrad:");
                    goto EnterStat;
                }
            Console.WriteLine("Enter student ID:");
            int inStudentID;
            int.TryParse(Console.ReadLine(), out inStudentID);
            student.StudentID = inStudentID;
            students.Add(student);
        }

        public static void AddLecturer()
        {
            Lecturer lecturer = new Lecturer();
            Console.WriteLine("Enter lecturer name:");
            lecturer.Name = Console.ReadLine();
            Console.WriteLine("Enter lecturer address:");
            lecturer.Address = Console.ReadLine();
            Console.WriteLine("Enter lecturer phone number:");
            lecturer.Phone = Console.ReadLine();
            Console.WriteLine("Enter lecturer email:");
            lecturer.Email = Console.ReadLine();
            Console.WriteLine("Enter lecturer PPSN:");
            lecturer.PPSN = Console.ReadLine();
            Console.WriteLine("Enter lecturer ID:");
            lecturer.ID = Console.ReadLine();
            Console.WriteLine("Enter salary:");
            lecturer.Salary = decimal.Parse(Console.ReadLine());
            Console.WriteLine("Enter subject taught:");
            lecturer.SubjectTaught = Console.ReadLine().ToLower();
            lecturers.Add(lecturer);
        }

        public static void SearchPerson()
        {
            int searchChoice = 0;
            int studentSearch = 0;
            int lecturerSearch = 0;
            Console.WriteLine("Press:");
            Console.WriteLine("1 to search for a student");
            Console.WriteLine("2 to search for a lecturer");
            int.TryParse(Console.ReadLine(), out searchChoice);

            switch (searchChoice)
            {
                //search students
                case 1:
                    Console.WriteLine("Press:");
                    Console.WriteLine("1 to search by name");
                    Console.WriteLine("2 to search by student number");
                    int.TryParse(Console.ReadLine(), out studentSearch);

                    switch (studentSearch)
                    {
                        case 1:
                            Console.WriteLine("Enter student name:");
                            string studentNameSearch = Console.ReadLine();
                            bool sFound = false;
                            foreach (Student student in students)
                            {
                                if (student.Name.Contains(studentNameSearch))
                                {
                                    Console.WriteLine(student.ToString());
                                    sFound = true;
                                    break;
                                }
                            }
                            if (sFound == false)
                            {
                                Console.WriteLine("Student name not found");
                            }
                            break;

                        case 2:
                            int studentIDSearch;
                            bool IDFound = false;
                            Console.WriteLine("Enter student number:");
                            int.TryParse(Console.ReadLine(), out studentIDSearch);
                            foreach (Student student in students)
                            {
                                if (student.StudentID.Equals(studentIDSearch))
                                {
                                    Console.WriteLine(student.ToString());
                                    IDFound = true;
                                    break;
                                }
                            }
                            if (IDFound == false)
                            {
                                Console.WriteLine("Student name not found");
                            }
                            break;

                        default:
                            Console.WriteLine("Invalid option selected");
                            break;
                    }
                    break;
                //search lecturers
                case 2:
                    Console.WriteLine("Press:");
                    Console.WriteLine("1 to search by name");
                    Console.WriteLine("2 to search by course taught");
                    int.TryParse(Console.ReadLine(), out lecturerSearch);

                    switch (lecturerSearch)
                    {
                        case 1:
                            Console.WriteLine("Enter lecturer name:");
                            string lecturerNameSearch = Console.ReadLine();
                            bool lFound = false;
                            foreach (Lecturer lecturer in lecturers)
                            {
                                if (lecturer.Name.Contains(lecturerNameSearch))
                                {
                                    Console.WriteLine(lecturer.ToString());
                                    lFound = true;
                                    break;
                                }
                            }
                            if (lFound == false)
                            {
                                Console.WriteLine("Lecturer name not found");
                            }
                            break;

                        case 2:
                            Console.WriteLine("Enter course taught:");
                            string lecturerSubjectSearch = Console.ReadLine().ToLower();
                            bool subjectFound = false;
                            foreach (Lecturer lecturer in lecturers)
                            {
                                if (lecturer.SubjectTaught.Contains(lecturerSubjectSearch))
                                {
                                    Console.WriteLine(lecturer.ToString());
                                    subjectFound = true;
                                    break;
                                }
                            }
                            if (subjectFound == false)
                            {
                                Console.WriteLine("Subject not found");
                            }
                            break;

                        default:
                            Console.WriteLine("Invalid option selected");
                            break;
                    }
                    break;

                default:
                    Console.WriteLine("Invalid option selected");
                    break;
            }
        }

        public static void ShowStudents()
        {
            //sort list by name
            List<Student> SortedStudents = students.OrderBy(o => o.Name).ToList();

            foreach (Student student in SortedStudents)
            {
                Console.WriteLine(student);
            }
        }

        public static void ShowLecturers()
        {
            //sort list by name
            List<Lecturer> SortedLecturers = lecturers.OrderBy(o => o.Name).ToList();

            foreach (Lecturer lecturer in SortedLecturers)
            {
                Console.WriteLine(lecturer.Name);
            }
        }

        public static void ShowPayrollDetails()
        {
            Console.WriteLine("Enter lecturer name:");
            string lecturerNameSearch = Console.ReadLine();
            for (int i = 0; i < lecturers.Count; i++)
            {
                if (lecturers[i].Name == lecturerNameSearch)
                {
                    Console.WriteLine(lecturers[i].PayrollDetails());
                }
                else
                {
                    Console.WriteLine("Lecturer name not found");
                }
            }
        }
    }
}

以下是我到目前为止创建的测试方法。

using Microsoft.VisualStudio.TestTools.UnitTesting;
using DBSManagement;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DBSManagement.Tests
{
    [TestClass()]
    public class CollegeTests
    {
        [TestMethod()]
        [ExpectedException(typeof(ArgumentException))]
        public void AddStudentTest()
        {
            //arrange 
            string s = "student";
            Status status = (Status)Enum.Parse(typeof(Status), s);
            //act
            Student student1 = new Student("Name", "123 Fake St", "0851234567", "fake@address.com", "7895459R", status, 12345678);
            //assert
            //handled by exception
        }

        [TestMethod()]
        public void AddLecturerTest()
        {
            Assert.Fail();
        }

        [TestMethod()]
        public void SearchPersonTest()
        {
            Assert.Fail();
        }

        [TestMethod()]
        public void ShowStudentsTest()
        {
            Assert.Fail();
        }

        [TestMethod()]
        public void ShowLecturersTest()
        {
            Assert.Fail();
        }

        [TestMethod()]
        public void ShowPayrollDetailsTest()
        {
            Assert.

这是学生班。如果有人进入postgrad或undergrad以外的状态,我试图让它抛出异常。这些是枚举。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DBSManagement
{
    public class Student : Person
    {
        private Status status;
        //auto-implemented properties
        public Status Status
        {
            get
            {
                return status;
            }
            set
            {
                if (value == Status.undergrad || value == Status.postgrad)
                {
                    status = value;
                }
                else throw new ArgumentException("Error: please select undergrad or postgrad");
            }
        }
        public int StudentID { get; set; }

        //empty constructor
        public Student() { }

        //constructor with parameters
        public Student(string name, string address, string phone, string email, string ppsn, Status status, int studentId)
            :base(name, address, phone, email, ppsn)
        {
            Status = status;
            StudentID = studentId;
        }

        //overridden ToString() method
        public override string ToString()
        {
            return string.Format("Name: {0}\nStudent Number: {1}\nAddress: {2}\nPhone: {3}\nEmail: {4}\nStatus: {5}",
                Name, StudentID, Address, Phone, Email, Status);
        }
    }
}

2 个答案:

答案 0 :(得分:1)

可以测试你的代码,但是这些测试会非常脆弱(正如@Scott Chamberlain指出的那样,它们将证明什么是不明确的。)

你需要做的是“隐藏”丑陋的Console.ReadLine()背后的“程序化”控制权。 Func<string>将是理想的:

public static void AddStudent(Func<string> consoleReader)
{
    Student student = new Student();

    Console.WriteLine("Enter student name:");
    student.Name = Console.ReadLine();
    // ...        
}

有了这个,你的测试就变成了:

[Test]
void TestAddStudent()
{
    var n = 0;
    var strings = new[] {
        "Name", 
        "123 Fake St", 
        "0851234567", 
        "fake@address.com", 
        "7895459R",
        // ...
    };

    Func<string> consoleReader = () => strings[n++];

    var student = AddStudent(consoleReader);

    Assert.AreEqual(strings[0], student.Name);
    // ...
}

答案 1 :(得分:1)

如果您想进行测试,那么将UI与逻辑分开会更容易。例如,您可以采用MVC模式或类似的东西。首先构建所有数据对象,如Lecturer,Student等。这些对象将是您的数据模型。然后添加操作这些数据对象的逻辑或控件。控件组件中可能有AddLecturer(..)方法。最后创建一个UI或视图,它与它们交互,而不像代码那样完全交织在一起。关于测试,您将主要编写控件组件中的方法测试,也许是模型。有很多东西需要测试。采取你的添加讲师方法:

  • 名称是否超过3个字符?
  • 至少有两个名字吗? (也许这是一个过于强烈的假设?)
  • 电话号码格式是否正确?
  • 电子邮件是否格式正确?
  • 讲师ID只是号码吗? (虽然,我希望讲师ID是由您的系统生成的)
  • PPSN格式正确吗?
  • 薪水是否为正?
  • 工资是否低得多?
  • 薪水是不是数字?`
  • lecturers添加新讲师时,确实添加了吗? (通常你不会检查这个。我们相信基本的收藏品,除非你自己写的。)