如何在Visual Studio 2017中创建单元测试(包括数据库)?

时间:2017-10-02 07:46:31

标签: c# unit-testing visual-studio-2017

这是我的代码:

public partial class ActivityService
    {
        public SearchActivityOutput GetActivityFromDbByName(SearchActivityInput input)
        {
            using (var conn = DbService.GetInstance().GetOpenConnection())
            {
                var savedActivities = GetSearchResultByNameQuery.GetInstance()
                    .Execute(conn, new { Name = input.Name });

                var activityList = savedActivities.Select(a => new ActivityDetail()
                {
                    Name = a.Name,
                    City = a.City,
                    Country = a.Country,
                    Description = a.Description,
                    OperationTime = a.OperationTime,
                    Price = a.Price
                }).ToList();

                var output = new SearchActivityOutput
                {
                    ActivityList = activityList
                };

                return output;
            }
        }
    }

如何从该课程中创建单元测试?

我对该课程的样本单元测试:

[TestMethod()]
        public void GetActivityFromDbByNameTest()
        {
            Initializer.Init();

            var input = new SearchActivityInput { Name = "Marjan" };

            var ActList1 = new ActivityDetail()
                { Name = "Marjan", City = "Bandung", Country = "Indonesia", Description = "coba", OperationTime = "24 Jam", Price = 2000};
            var ActList2 = new ActivityDetail()
                { Name = "Marjan", City = "Bandung", Country = "Indonesia", Description = "coba", OperationTime = "24 Jam", Price = 3500 };
            var ActList3 = new ActivityDetail()
                { Name = "Marjan aja", City = "Jakarta", Country = "Indonesia", Description = "apapun", OperationTime = "2 Hari", Price = 4500 };
            var ActList4 = new ActivityDetail()
                { Name = "Marjan", City = "Stockholm", Country = "Swedia", Description = "123coba", OperationTime = "3 Jam", Price = 3500 };
            var ActList5 = new ActivityDetail()
                { Name = "Marjan", City = "Stockholm", Country = "Swedia", Description = "123coba", OperationTime = "3 Jam", Price = 4500 };
            var ActList6 = new ActivityDetail()
                { Name = "Marjan aja", City = "Jakarta", Country = "Indonesia", Description = "apapun", OperationTime = "2 Hari", Price = 2000 };
            var ActList7 = new ActivityDetail()
                { Name = "Marjan", City = "Stockholm", Country = "Swedia", Description = "123coba", OperationTime = "3 Jam", Price = 3500 };
            var ActList8 = new ActivityDetail()
                { Name = "Marjan", City = "Stockholm", Country = "Swedia", Description = "123coba", OperationTime = "3 Jam", Price = 2000 };
            var ActList9 = new ActivityDetail()
                { Name = "Marjan", City = "Stockholm", Country = "Swedia", Description = "123coba", OperationTime = "3 Jam", Price = 2000 };
            var ActList = new List<ActivityDetail>();
            ActList.Add(ActList1);
            ActList.Add(ActList2);
            ActList.Add(ActList3);
            ActList.Add(ActList4);
            ActList.Add(ActList5);
            ActList.Add(ActList6);
            ActList.Add(ActList7);
            ActList.Add(ActList8);
            ActList.Add(ActList9);
            var expectedResult = new SearchActivityOutput
            {
                ActivityList = ActList
            };
            using (var conn = DbService.GetInstance().GetOpenConnection())
            {
                var actualResult = ActivityService.GetInstance().GetActivityFromDbByName(input);
                Assert.AreEqual(expectedResult, actualResult);
            }

        }

但是,当我运行单元测试时,会出现一些错误消息:

  

测试名称:GetActivityFromDbByNameTest测试

     

结果StackTrace:at   xxxx.ActivityServiceTests.GetActivityFromDbByNameTest()   在

     

70结果消息:Assert.AreEqual失败。   预计:(xxx.yyy.zzz.Model.SearchActivityOutput)。   实际:(xxx.yyy.zzz.Model.SearchActivityOutput)

3 个答案:

答案 0 :(得分:2)

在进行单元测试时,不应使用数据库。

维基百科说:一个常见的例子是依赖于数据库的类:为了测试类,测试人员经常编写与数据库交互的代码。这是一个错误,因为单元测试通常不应超出其自己的类边界,尤其不应跨越此类进程/网络边界,因为这会给单元测试套件带来不可接受的性能问题。

使用代表您的数据库的testdata或虚拟类。 https://softwareengineering.stackexchange.com/questions/119367/should-service-test-classes-connect-to-the-database

https://softwareengineering.stackexchange.com/questions/138238/unit-testing-database-coupled-app/138257#138257

答案 1 :(得分:1)

您无法对执行任何与I / O相关的任务的类进行单元测试。即使您的测试似乎在您的开发计算机上运行正常,它们也可能会在您的同事的计算机或CI服务器上失败。

为了使您的代码片段可测试,它应该是一个纯函数,或者它应该可以使用一些抽象技术(如IoC /高阶函数/等)简化为纯函数。

首先学习编写可测试代码。本文将为您提供一些建议 - https://www.toptal.com/resume/sergey-kolodiy(我是其作者)。

答案 2 :(得分:0)

我完全同意在单元测试中不使用数据库的其他声明,但是您当前正在接收的失败的答案是您应该使用CollectionAssert类的方法来比较内容两个集合,而不是您正在使用的Assert类。如果您只想确保返回的List包含相同的元素而不管顺序如何,您可以使用

CollectionAssert.AreEquivalent(expectedResult, actualResult);

如果排序顺序很重要,您应该使用

CollectionAssert.AreEqual(expectedResult, actualResult);