.net测试篇之单元测试/集成测试神器Autofixture

系列目录html

autofixture简介

有了单元测试框架加上Moq(后面咱们会用单独章节来介绍moq),能够说测试问题基上都能搞定了.然而有了AutoFixture对单元测试来讲能够说是如虎添翼,AutoFixture而且它能与moq,rhinomock等框架结合,对单元测试带来的便捷性,可维护性和扩展性更是难以言表,只有用用了才知道.web

说了这么多,尚未介绍AutoFixture是干什么的,其实AutoFixture就是一个假数据填充工具.数据库

其实不管是Nunit仍是Xunit都有数据填充功能,而且大部分时候都能知足需求.然而经过咱们前面的介绍就会知道有如下问题:框架

  • 不管是vlues注解仍是TestCase注解都没有类型约束,这就可能会形成运行时错误.
  • 基于注解的值都只能是Const值,若是须要复杂类型就须要定义一个类型作为Source为当前操做提供值.
  • 与Nunit和Xunit生成的填充数据相比,Autofixture能够生成符合验证规则的数据(基于system.componentmodel.annotations名称空间下的注解约束),这在集成测试里帮助很大,对于有着很是复杂模型验证的接口来讲,手工制造出符合模型验证规则的数据每每是很是痛苦的.
  • Autofixture能够生成一组符合验证规则的数据,这样在测试的时候增长了样本数据的随机性,大大提高了测试的覆盖面.

Moq测试虽然极大方便了测试,可是也会有一些问题:函数

  • 对于比较复杂的web项目,每每一个业务逻辑可能要消费十个几个甚至几十个数据接口,若是业务不是很成熟可能须要不断的来调整这些接口,这里的修改同时单元测试方法也须要修改(由于这些接口多数时候是经过构造函数注入的,构造函数参数数量的变更会致使调用者也须要作相应调整)工具

  • 虽然Moq也可以模拟类对象,可是限制很是多,咱们不可能为了测试把全部的方法和属性都加上abstract或者virtual.单元测试

而autofixture则能够很好的解决这些问题.这样极大增长代码的可维护性和扩展性.测试

AutoFixture并非对moq的替代,它只能填充对象,而不能模拟对象,可是它能够与moq框架结合实现更强大的功能.调试

autofixture安装

autofixture安装很是简单,咱们在Nuget里搜索autofixture,第一个就是它点击安装便可.code

关于autofixture与moq结合须要的包在后面讲到的时候再安装,这里先略过.

AutoFixture 自动为Nunit填充数据

要使AutoFixture与Nunit结合,首先咱们须要安装特定的包.

在Nuget里输入AutoFixture.Nunit3,会出现如下选项
Avatar
因为咱们使用的是Nunit3,所以咱们选择第一个安装.

AutoFixture还能够与Xunit结合.在Nuget里搜索AutoFixture.xunit2即可以搜索到AutoFixture与Xunit结合的框架.与Xunit结果的用法与Nunit差很少,只是须要注意Xunit数据测试方法须要Theory注解.

咱们新建一个名为FixtureTest并引入AutoFixture.NUnit3;名称空间

代码以下

[TestFixture]
   public class FixtureTest
    {
        [Test]
        [AutoData]
        public void FixValueTest(int a, int b)
        {
            var result = Add(a , b);
            Assert.AreEqual(a + b, result);
        }
        int Add(int x, int y)
        {
            return x + y;
        }
    }

这里与平时的单元测试相比,多了一个AutoData注解,有了AutoData注解,AutoFixture即可以给当前测试提供值了.
咱们断点调试一下看看a和b的值

Avatar

咱们能够看到a和b都被赋予了随机的值.

咱们把测试代码改成以下

[Test]
        [AutoData]
        public void FixValueTest(Person p1, Person p2)
        {
            var result = Add(p1.Age , p2.Age);
            Assert.AreEqual(p1.Age + p2.Age, result);
        }

咱们再断点调试一下看看是否有值
Avatar

复杂对象它也能填充!这样就免去了为了使用复杂对象须要额外写不少source繁琐.

咱们把代码改为以下

[Test]
        [AutoData]
        public void FixValueTest(IEnumerable<Person> people)
        {
            var ages = people.Sum(a => a.Age);
        }

咱们看看此时会有什么结果
Avatar

经过监视容器能够看到,AutoFixture生成了一个包含三个元素的对象.

这简直是太方便了,autofixture自动填充值不但减小了运行时可能的类型错误,还有极大的扩展性,若是咱们在测试方法上添加其它参数,它仍然可以自动填充.而使用Nunit自身带的TestCase若是参数减小,里面指定的值也要减小,不然会抛出运行时异常.

经过以上咱们能够看到,AutoFixture能够生成各类类型的对象,它能够建立集合对象对咱们测试来讲尤为有用,免去了手动建立的麻烦.可是咱们同时也看到,基于注解的方法生成集合时只生成了三个,实际上要模拟数据库是的数据测试一些行为咱们可能须要更多的元素.这里就须要对AutoFixture自己进行配置.这是基于注解的方法没法完成的.