201陆.陆.二7 微软现已正式揭露了.NET Core 一.0
RTM,不过工具链依然预览版,同样的大方的开源测试库也都是最少发表了Alpha测试版帮助.NET
Core, 那篇小说 The State of .Net Core Testing
Today
就将顺序开源测试库的当下拓展举办了汇总。本文大家的目的是在大家打造大家应用程序的时候能够举办测试,怎么样运用XUnit结合你能够透过为您的种类增进分歧的测试用例NSubstitute进行单元测试,同时对全体项目实行集成测试。这一次大家选拔Visual
Studio 201五 Update 三举办编写 。xUnit.net是基于.NET Framework
的开源测试工具。通过xUnit.net可以针对C#/F#/VB.NET等进行单元测试。ASP.NET
Core 更加直白把昔日的Visual Studio Unit Test Framework
说再见了,而一直选取上了xUnit.net,xUnit.net基于NUnit
。从网址只怕官英特网,你能够找到不少xUnit的独到之处,与NUnit和其它测试框架比较有须臾间有个别优势 
         壹)为种种测试方法发生2个对象实例
         2)取消了[SetUp]和[TearDown]
         3)取消了[ExpectedException]
         4)类似于Aspect的功能
         伍)裁减了自定义属性(Attribute)的数据
         陆)选择泛型
         七)无名委托
         八)可增加的预知
         玖)可扩张的测试方法
         拾)可扩大的测试类

201陆.六.2七 微软已经正式公告了.NET Core 一.0
RTM,不过工具链还是预览版,同样的大气的开源测试库也都以致少发表了Alpha测试版辅助.NET
Core, 这篇文章 The State of .Net Core Testing
Today
就将顺序开源测试库的此时此刻进行实行了汇总。本文大家的目标是在大家营造大家应用程序的时候能够举行测试,怎么着行使XUnit结合你能够透过为你的品种增加分化的测试用例NSubstitute举办单元测试,同时对全部项目进行合并测试。此次我们选拔Visual
Studio 二〇一四 Update 三进行编写 。xUnit.net是基于.NET Framework
的开源测试工具。通过xUnit.net能够针对C#/F#/VB.NET等开始展览单元测试。ASP.NET
Core 更加直白把昔日的Visual Studio Unit Test Framework
说再见了,而直白运用上了xUnit.net,xUnit.net基于NUnit
。从网址依然官英特网,你能够找到不少xUnit的独到之处,与NUnit和其余测试框架相比较有须臾间片段优势 
         一)为种种测试方法产生一个对象实例
         2)取消了[SetUp]和[TearDown]
         3)取消了[ExpectedException]
         4)类似于Aspect的功能
         5)裁减了自定义属性(Attribute)的数码
         六)采纳泛型
         七)无名氏委托
         8)可扩充的预感
         玖)可增添的测试方法
         十)可扩张的测试类

Unit Test

        
掌握更加多关于xUnit.net可以参考那里(点击展开链接[舍弃Nunit拥抱Xunit])。

        
精通越来越多关于xUnit.net能够参见那里(点击展开链接[舍弃Nunit拥抱Xunit])。

一.建立单元测试
新建3个类库项目,在Nuget中寻找xunit,选拔 xUnit.net 和
xunit.runner.visualstudio 插件包设置。
xunit.runner.visualstudio(测试财富管理器),安装之后能够在
‘测试–》窗口–》测试能源管理器’ 打开测试财富管理器分界面
* 假设想在CMD下调节和测试,能够安装xunit.runner.console 插件包

 

 

二.xUnit.Net常用的暗号(Fact 事实)
[Fact] 标志为测试方法,可设置参数:Skip,DisplayName,Timeout
[Fact(Skip =”跳过测试”)]//一时半刻忽略被标识的形式
[Fact(DisplayName =”通过测试”)]
[Theory] 同盟InlineData能够直接在贰个方式中测试多组参数

接纳xUnit.net 单元测试

行使xUnit.net 单元测试

3.xUnit.Net的断言(Assertions)
//Assert.Equal(resultModel.eAccountID, 1169676);
Equal 相等相比较
NotEqual 不等于比较
NotEmpty 不为空
Contains ……
* Model相比较能够用 CompareNETObjects,在 Nuget 中查询 CompareNETObjects
插件包安装

 

 

private CompareLogic compareLogic;
compareLogic = new CompareLogic();

 

 

第一大家好像于.NET Core连串 :3、使用多个体系
成立三个消除方案testdemo,增添二个类库项目名叫DotnetCoreLib,Library.cs
也交替为:

namespace DotnetCoreLib
{
    public class Calculator
    {
        public int Multi(int x, int y)
        {
            return x * y;
        }
    }

}

图片 1

上边大家要成立1个针对性DotnetCoreLib的测试项目,具体制造进度大家参照小说

,大家修改DotnetCoreLibTest 项目标project.json
,扩充XUnit相关的nuget包引用,并修改部根据地署。

 

图片 2 

再有我们设置Framework节点为 netcoreapp一.0, 正视的xunit
和xunit.runner的包

“dependencies”: {
    “dotnet-test-xunit”: “2.2.0-preview2-build1029”,
    “DotnetCoreLib”: {
      “version”: “1.0.0-*”,
      “target”: “project”
    },
    “xunit”: “2.2.0-beta2-build3300”,
    “xunit.runner.console”: “2.2.0-beta2-build3300”
  }

 

Calculator接下去就从头测试我们的类库Calculator,
修改Class一.cs为CalculatorTest.cs ,

 

using DotnetCoreLib;
using Xunit;

 

namespace DotnetCoreLibTest
{
    public class CalTest
    {
        private readonly Calculator calculator;

        public CalTest()
        {
            calculator = new Calculator();
        }

 

        [Fact]
        public void OneMutiOneIsOne()
        {
            var result = calculator.Multi(1, 1);
            Assert.Equal(1, result);
        }

 

        [Theory]
        [InlineData(-1)]
        [InlineData(0)]
        [InlineData(1)]
        public void ReturnValue(int value)
        {
            var result = calculator.Multi(1,value);

            Assert.Equal(result, value);
        }
    }
}

 

地点的四个测试,我们分别用了二天性状[Fact] 和[Theory],
[Fact]属性表示为3个艺术的单个测试,[Theory]属性表示实施同样的代码,不过有例外的输入的参数的测试套件。[InlineData]
属性可用于钦命为那个输入值。通过特色[Fact]
和[Theory],xUnit就领悟了那是个测试方法,然后运维那一个点子。在二个测试方法中,我们一般根据包蕴三步骤的AAA模式:

  1. Arrange:为测试策动
  2. Act:运作SUT(实际测试的代码)
  3. Assert:校验结果

上边大家运营dotnet test 就足以看来结果了。

C:\Users\geffz\Documents\Visual Studio
2015\Projects\TestDemo\DotnetCoreLibTest>dotnet test
Project DotnetCoreLib (.NETCoreApp,Version=v1.0) was previously
compiled. Skipping compilation.
Project DotnetCoreLibTest (.NETCoreApp,Version=v1.0) was previously
compiled. Skipping compilation.
xUnit.net .NET CLI test runner (64-bit .NET Core win10-x64)
  Discovering: DotnetCoreLibTest
  Discovered:  DotnetCoreLibTest
  Starting:    DotnetCoreLibTest
  Finished:    DotnetCoreLibTest
=== TEST EXECUTION SUMMARY ===
   DotnetCoreLibTest  Total: 4, Errors: 0, Failed: 0, Skipped: 0, Time:
0.206s
SUMMARY: Total: 1 targets, Passed: 1, Failed: 0.

 

地方的出口大家领悟已经推行了多少个测试,都由此了,[Face]特征标志表示固定输入的测试用例,而[Theory]性格标记表示能够钦点多少个输入的测试用例,结合InlineData性情标记应用。在上边的事例里,总共使用了3次InlineData个性标志,每一次设定的值都不可同日而语,在实施单元测试时,设定的值会被测试框架赋值到相应的测试方法的参数里。你可以因此为您的品类拉长差别的测试用例,那样就足以让您的代码获得丰裕测试。

 

 

 

先是大家好像于.NET Core种类 :3、使用四个品种
创设一个解决方案testdemo,增加1个类库项目名叫DotnetCoreLib,Library.cs
也交替为:

namespace DotnetCoreLib
{
    public class Calculator
    {
        public int Multi(int x, int y)
        {
            return x * y;
        }
    }

}

图片 1

上面大家要开创二个对准DotnetCoreLib的测试项目,具体创制进度大家参照小说

,大家修改DotnetCoreLibTest 项目的project.json
,扩展XUnit相关的nuget包引用,并修改部根据地署。

 

图片 2 

还有我们设置Framework节点为 netcoreapp1.0, 倚重的xunit
和xunit.runner的包

“dependencies”: {
    “dotnet-test-xunit”: “2.2.0-preview2-build1029”,
    “DotnetCoreLib”: {
      “version”: “1.0.0-*”,
      “target”: “project”
    },
    “xunit”: “2.2.0-beta2-build3300”,
    “xunit.runner.console”: “2.2.0-beta2-build3300”
  }

 

Calculator接下去就起始测试大家的类库Calculator,
修改Class一.cs为CalculatorTest.cs ,

 

using DotnetCoreLib;
using Xunit;

 

namespace DotnetCoreLibTest
{
    public class CalTest
    {
        private readonly Calculator calculator;

        public CalTest()
        {
            calculator = new Calculator();
        }

 

        [Fact]
        public void OneMutiOneIsOne()
        {
            var result = calculator.Multi(1, 1);
            Assert.Equal(1, result);
        }

 

        [Theory]
        [InlineData(-1)]
        [InlineData(0)]
        [InlineData(1)]
        public void ReturnValue(int value)
        {
            var result = calculator.Multi(1,value);

            Assert.Equal(result, value);
        }
    }
}

 

上边的五个测试,大家独家用了2本性状[Fact] 和[Theory],
[Fact]属性表示为3个艺术的单个测试,[Theory]品质表示施行同一的代码,可是有分裂的输入的参数的测试套件。[InlineData]
属性可用来钦赐为这一个输入值。通过特征[Fact]
和[Theory],xUnit就知晓了那是个测试方法,然后运转这几个方法。在一个测试方法中,大家一般遵守包蕴三步骤的AAA模式:

  1. Arrange:为测试策画
  2. Act:运作SUT(实际测试的代码)
  3. Assert:校验结果

下边大家运转dotnet test 就足以见见结果了。

C:\Users\geffz\Documents\Visual Studio
2015\Projects\TestDemo\DotnetCoreLibTest>dotnet test
Project DotnetCoreLib (.NETCoreApp,Version=v1.0) was previously
compiled. Skipping compilation.
Project DotnetCoreLibTest (.NETCoreApp,Version=v1.0) was previously
compiled. Skipping compilation.
xUnit.net .NET CLI test runner (64-bit .NET Core win10-x64)
  Discovering: DotnetCoreLibTest
  Discovered:  DotnetCoreLibTest
  Starting:    DotnetCoreLibTest
  Finished:    DotnetCoreLibTest
=== TEST EXECUTION SUMMARY ===
   DotnetCoreLibTest  Total: 4, Errors: 0, Failed: 0, Skipped: 0, Time:
0.206s
SUMMARY: Total: 1 targets, Passed: 1, Failed: 0.

 

上边的出口我们领略已经施行了五个测试,都通过了,[Face]本性标志表示一定输入的测试用例,而[Theory]特征标记表示可以钦赐三个输入的测试用例,结合InlineData性情标志应用。在上头的例子里,总共使用了三遍InlineData个性标志,每趟设定的值都不可同日而语,在实行单元测试时,设定的值会被测试框架赋值到对应的测试方法的参数里。你能够透过为你的品类拉长分化的测试用例,那样就足以让您的代码得到充足测试。

 

var expectedResult = GetCaseModel();
ComparisonResult compareResult = compareLogic.Compare(expectedResult,
new Case() { CaseID = 1, BankCode = “2” });
Assert.Equal(true, compareResult.AreEqual);

xUnit.net 搭配NSubstitute 进行单元测试

 

  
在贰个支行结构清晰的种类里,各层之间依赖于事先约定好的接口。在几人搭档开辟时,大多数人都只会顶住和谐的那部分模块功效,开辟进程平时状态下也不雷同。当有个别开荒职员须求对团结的模块举行单元测试而借助的别样模块还从未开拓变成时,则须要对依赖的接口通过Mock的不二等秘书籍提供模拟效用,从而实未来不实际正视其余模块的实际职能的情事下产生本人模块的单元测试专门的学问。那时大家平时须求有叁个单元测试模拟类库,一直以来,开荒者对
mocking 类库的语法的简洁性有醒目标供给,NSubstitute
试图知足那壹急需。简单明了的语法能够让我们将主体放在测试自个儿,而不是纠缠在测试代替实例的始建和布局上。NSubstitute
已尝试将最常用的操作必要轻松化、易用化,并帮忙部分不常用的或查究性的机能,与此同时还尽量地将其语法向自然语言靠近。关于NSubstitute的更详细新闻请往
NSubstitute完全手册索引。

 

NSubstitute 已经发表2.0 EscortC版本协理.NET Core。引进NSubstitute
相关nuget包:

图片 5

大家把Calculator 类重构下提抽出接口ICalculator:

    public interface ICalculator
    {
        int Multi(int x, int y);
    }

 

咱俩得以让NSubstitute来创造项目实例的代表实例,能够成立诸如
Stub、Mock、Fake、Spy、Test Double
等,但当我们只是想要多少个能有早晚程度决定的代表实例时,为何我们要麻烦于此呢?大家能够告诉被创制的代表实例,当方法被调用时回来3个值:

     [Fact]
      public void Test_GetStarted_ReturnSpecifiedValue()
      {
          ICalculator calculator =
Substitute.For<ICalculator>();
          calculator.Multi(1, 2).Returns(2);

          int actual = calculator.Multi(1, 2);
          Assert.Equal(2, actual);
      }

上面大家运营dotnet test
就可以观察结果了,扩大了地方的一个用例,关于NSubstitute的更详细音信请往
NSubstitute完全手册索引。

图片 6

 

xUnit.net 搭配NSubstitute 实行单元测试

 

  
在三个支行结构清晰的品种里,各层之间依赖于事先约定好的接口。在四个人合营开荒时,大多数人都只会担任自身的那有些模块作用,开辟进程平时情形下也不平等。当有些开拓人士须要对本人的模块实行单元测试而借助的其余模块还未有支付成功时,则要求对借助的接口通过Mock的法子提供模拟成效,从而实今后不实际正视其余模块的切切实实际效果果的情状下成功自身模块的单元测试专门的学业。那时大家平常需求有二个单元测试模拟类库,平素以来,开垦者对
mocking 类库的语法的简洁性有强烈的急需,NSubstitute
试图满意那1须求。轻松明了的语法能够让大家将重视放在测试自身,而不是纠缠在测试取代实例的创办和配备上。NSubstitute
已尝试将最常用的操作须要简单化、易用化,并支持部分不常用的或探寻性的功用,与此同时还尽量地将其语法向自然语言靠近。关于NSubstitute的更详细音信请往
NSubstitute完全手册索引。

 

NSubstitute 已经宣布二.0 本田CR-VC版本帮助.NET Core。引进NSubstitute
相关nuget包:

图片 5

咱们把Calculator 类重构下提收取接口ICalculator:

    public interface ICalculator
    {
        int Multi(int x, int y);
    }

 

作者们得以让NSubstitute来成立项目实例的代替实例,能够创立诸如
Stub、Mock、Fake、Spy、Test Double
等,但当我们只是想要贰个能有自然程度决定的代表实例时,为啥大家要麻烦于此呢?大家得以告知被创设的代表实例,当方法被调用时回来二个值:

     [Fact]
      public void Test_GetStarted_ReturnSpecifiedValue()
      {
          ICalculator calculator =
Substitute.For<ICalculator>();
          calculator.Multi(1, 2).Returns(2);

          int actual = calculator.Multi(1, 2);
          Assert.Equal(2, actual);
      }

下边我们运营dotnet test
就能够看出结果了,扩大了地点的1个用例,关于NSubstitute的更详细新闻请往
NSubstitute完全手册索引。

图片 6

 

4.在XUnit中使用Moq模拟EntityFramework Core下的DbSet
在 Nuget 中查询 Moq 插件包安装

合龙测试

下面大家只是对逻辑进行了单元测试。对于Asp.Net
Core项目,还亟需效法在网址计划的情况下对一一请求入口实行测试。NET Core
可为急忙轻巧集成测试提供丰富棒的支持。

TestServer 类为 ASP.NET Core
中的集成测试奉行超越八分之四千斤操作,Microsoft.AspNetCore.TestHost
包中存有此类。本节内容来自于MSDN杂志《 ASP.NET Core – 实际的 ASP.NET
Core MVC
筛选器》,这个合并测试不必要数据库或
Internet 连接或运转的 Web
服务器。它们仿佛单元测试同样神速轻巧,但最关键的是,它们允许你在全路请求管道中测试
ASP.NET
应用,而不只是决定器类中的孤立方法。提议尽量编写单元测试,并针对性无法单元测试的行事退回到集成测试,但运用此类高品质格局在
ASP.NET Core 中运维集成测试是不行棒的。

 

通过在三个工程里还要效仿了服务端(TestServer)和客户端(HttpClient)的通讯,从而到达了一体化测试WebApi接口的目标,相关的代码放在
。小说对ASP.NET CORE
MVC的筛选器实行测试,由于很难通过编写制定单元测试来测试此类现象,可是足以经过ASP.NET
Core 的融会测试来达到平等的目标。

using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using Filters101;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;

 

namespace IntegrationTests
{
    public class AuthorsControllerTestBase
    {
        protected HttpClient GetClient()
        {
            var builder = new WebHostBuilder()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .UseEnvironment(“Testing”);
            var server = new TestServer(builder);
            var client = server.CreateClient();

            // client always expects json results
            client.DefaultRequestHeaders.Clear();
            client.DefaultRequestHeaders.Accept.Add(
                new
MediaTypeWithQualityHeaderValue(“application/json”));

            return client;
        }
    }
}

 

 

using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Filters101.Models;
using Newtonsoft.Json;
using Xunit;

namespace IntegrationTests.AuthorsController
{
    public class Get : AuthorsControllerTestBase
    {
        private readonly HttpClient _client;

        public Get()
        {
            _client = base.GetClient();
        }

        [Theory]
        [InlineData(“authors”)]
        [InlineData(“authors2”)]
        public async Task ReturnsListOfAuthors(string controllerName)
        {
            var response = await
_client.GetAsync($”/api/{controllerName}”);
            response.EnsureSuccessStatusCode();
            var stringResponse = await
response.Content.ReadAsStringAsync();
            var result =
JsonConvert.DeserializeObject<IEnumerable<Author>>(stringResponse).ToList();

            Assert.Equal(2, result.Count());
            Assert.Equal(1, result.Count(a => a.FullName == “Steve
Smith”));
            Assert.Equal(1, result.Count(a => a.FullName == “Neil
Gaiman”));
        }
    }
}

此案例中的客户端是正经的
System.Net.Http.HttpClient,你能够运用它向服务器发出请求,正就像通过网络同样。但因为具备请求都在内部存款和储蓄器中张开,所以测试最佳便捷可信。在cmd窗口实行单元测试,查看测试结果

图片 9

合并测试

地点我们只是对逻辑进行了单元测试。对于Asp.Net
Core项目,还亟需效法在网址计划的事态下对各种请求入口举行测试。NET Core
可为快捷轻易集成测试提供相当棒的支撑。

TestServer 类为 ASP.NET Core
中的集成测试实践当先十分之四千斤操作,Microsoft.AspNetCore.TestHost
包中享有此类。本节内容来自于MSDN杂志《 ASP.NET Core – 实际的 ASP.NET
Core MVC
筛选器》,这个合并测试不要求数据库或
Internet 连接或运维的 Web
服务器。它们犹如单元测试同样便捷轻松,但最要害的是,它们允许你在全数请求管道中测试
ASP.NET
应用,而不只是调节器类中的孤立方法。建议尽量编写单元测试,并针对无法单元测试的作为退回到集成测试,但运用此类高品质格局在
ASP.NET Core 中运维集成测试是充足棒的。

 

因此在二个工程里还要效仿了服务端(TestServer)和客户端(HttpClient)的通讯,从而达成了一体化测试WebApi接口的目标,相关的代码放在
。作品对ASP.NET CORE
MVC的筛选器实行测试,由于很难通过编写制定单元测试来测试此类现象,不过能够通过ASP.NET
Core 的集成测试来完毕同等的目标。

using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using Filters101;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.TestHost;

 

namespace IntegrationTests
{
    public class AuthorsControllerTestBase
    {
        protected HttpClient GetClient()
        {
            var builder = new WebHostBuilder()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .UseEnvironment(“Testing”);
            var server = new TestServer(builder);
            var client = server.CreateClient();

            // client always expects json results
            client.DefaultRequestHeaders.Clear();
            client.DefaultRequestHeaders.Accept.Add(
                new
MediaTypeWithQualityHeaderValue(“application/json”));

            return client;
        }
    }
}

 

 

using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Filters101.Models;
using Newtonsoft.Json;
using Xunit;

namespace IntegrationTests.AuthorsController
{
    public class Get : AuthorsControllerTestBase
    {
        private readonly HttpClient _client;

        public Get()
        {
            _client = base.GetClient();
        }

        [Theory]
        [InlineData(“authors”)]
        [InlineData(“authors2”)]
        public async Task ReturnsListOfAuthors(string controllerName)
        {
            var response = await
_client.GetAsync($”/api/{controllerName}”);
            response.EnsureSuccessStatusCode();
            var stringResponse = await
response.Content.ReadAsStringAsync();
            var result =
JsonConvert.DeserializeObject<IEnumerable<Author>>(stringResponse).ToList();

            Assert.Equal(2, result.Count());
            Assert.Equal(1, result.Count(a => a.FullName == “Steve
Smith”));
            Assert.Equal(1, result.Count(a => a.FullName == “Neil
Gaiman”));
        }
    }
}

该案例中的客户端是行业内部的
System.Net.Http.HttpClient,你能够应用它向服务器发出请求,正就像通过网络同样。但因为兼具请求都在内部存款和储蓄器中打开,所以测试最佳火速可信赖。在cmd窗口进行单元测试,查看测试结果

图片 9

 

单元测试中应用Moq对EF的DbSet实行mock

刚用上Moq,就用它化解了一个IUnitOfWork的mock难点

 

代码地址:

相关文章