Fluent Assertions 集合 collection 断言

使用Fluent assertions对Collection集合的断言,是非常方便的。

var collection = new[] { 1, 2, 5, 8 };

collection.Should().NotBeEmpty() //不是空集合
    .And.HaveCount(4) // 并且必须有4个元素
    .And.ContainInOrder(new[] { 2, 5 }) // 包含 2,5  并且是有序的, 2,5 换成 2,1 就会出错
    .And.ContainItemsAssignableTo<int>(); // 元素可以被赋值成 int类型

collection.Should().Equal(new List<int> { 1, 2, 5, 8 }); // 判断是否相等,元素一样就可以
collection.Should().Equal(1, 2, 5, 8);

//元素是否相等,不管排序,这个我们是最常用的。
collection.Should().BeEquivalentTo(8, 2, 1, 5);
collection.Should().NotBeEquivalentTo(new[] { 8, 2, 3, 5 });

collection.Should().HaveCount(c => c > 3)
    .And.OnlyHaveUniqueItems();//元素是否具有唯一性

// 个数超过3个
collection.Should().HaveCountGreaterThan(3);
// 个数超过或等于 4个
collection.Should().HaveCountGreaterOrEqualTo(4);
// 个数小于或等于 4个
collection.Should().HaveCountLessOrEqualTo(4);
// 个数小于 5个
collection.Should().HaveCountLessThan(5);
// 个数不是3个
collection.Should().NotHaveCount(3);
// 跟另一个集合比对有相同个数
collection.Should().HaveSameCount(new[] { 6, 2, 0, 5 });
// 跟另一个集合比对有不同的个数
collection.Should().NotHaveSameCount(new[] { 6, 2, 0 });

// 第一个元素是1, (开始于1)
collection.Should().StartWith(1);
//元素开始 1,2
collection.Should().StartWith(new[] { 1, 2 });
//元素结束于 8
collection.Should().EndWith(8);
// 元素结束于5,8 有序的
collection.Should().EndWith(new[] { 5, 8 });

// 是不是参数的子集
collection.Should().BeSubsetOf(new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, });


//collection.Should().ContainSingle(); // 只包含一个元素 会出错
// collection.Should().ContainSingle(x => x > 3); // 只有一个大于3, 会出错
collection.Should().Contain(8)
    .And.HaveElementAt(2, 5) // 索引2的位置是5 (C#这种索引也是从0开始的)
    .And.NotBeSubsetOf(new[] { 11, 56 }); //不是 11 56的子集

collection.Should().Contain(x => x > 3); // 含有大于3的元素 (这个是predicate 可以自己写各种需要判断)
var expected = new[] { 9 };
collection.Should().Contain(expected, "出错了{0}{1}", 5, 6); //出错了, Expected collection {1, 2, 5, 8} to contain 9 because 出错了56.

collection.Should().OnlyContain(x => x < 10); //只包含符合条件的 小于 10 的元素
collection.Should().ContainItemsAssignableTo<int>();  //所有的元素必须可以赋值给int类型

collection.Should().ContainInOrder(new[] { 1, 5, 8 }); // 包含 1 5 8 元素 有序的

collection.Should().NotContain(82); // 不包含82
collection.Should().NotContain(new[] { 82, 83 }); //  // 不包含82 83 有序的      
collection.Should().NotContainNulls(); // 不包含 null
collection.Should().NotContain(x => x > 10); // 不包含大于10

object boxedValue = 2;
collection.Should().ContainEquivalentOf(boxedValue); // 内部比较的时候是用Object.Equals 来比较的


collection = new[] { 1, 2, 9, 5, 8 };
// 在5之前的元素
collection.Should().HaveElementPreceding(5, 9);
//9 后面的元素 5
collection.Should().HaveElementSucceeding(9, 5);

//collection.Should().BeEmpty(); // 为空 有元素所以 断言失败
//collection.Should().BeNullOrEmpty();// 为空或者为null 断言失败
collection.Should().NotBeNullOrEmpty(); // 不为空或者不为Empty

var otherCollection = new[] { 1, 2, 5, 8, 1 };
var anotherCollection = new[] { 10, 20, 50, 80, 10 };
//跟参数的集合有交集
collection.Should().IntersectWith(otherCollection);
//跟参数的集合没有交集
collection.Should().NotIntersectWith(anotherCollection);

collection = new[] { 1, 2, 5, 8 };
collection.Should().BeInAscendingOrder(); //是否是升序排列。
//collection.Should().BeInDescendingOrder(); //是否倒序
// collection.Should().NotBeInAscendingOrder(); // 不是升序
collection.Should().NotBeInDescendingOrder(); //不是倒序

var stringCollection = new[] { "build succeded", "test failed" };
stringCollection.Should().ContainMatch("* failed"); //通配符判断 有没有 * failed 字符串

集合元素是复杂对象

有时候集合里面的对象不是简单类型,我们可以用Lambda语法,把它取出来再断言。

using FluentAssertions;
using System.Linq;
using Xunit;
namespace MyFirstUnitTests
{
    public class MyTestClass
    {
        [Fact]
        public void Test_Example1()
        {
            var students1 = new[] {
                new Student() { Name = "a1" },
                new Student() { Name = "a2" }
            };

            var students2 = new[] {
                new Student() { Name = "a1" },
                new Student() { Name = "a2" },
            };

            // 把name取出 集合变成了 a1 a2, 断言元素都是唯一的
            students1.Select(x => x.Name).Should().OnlyHaveUniqueItems();

            // students1 的名字跟 students2 是不是相等, 内部的每一个元素都要相等
            students1.Select(c => c.Name).Should().Equal(students2.Select(c => c.Name));
         
            students1.Select(c => c.Name).Should().StartWith(students2.Select(c => c.Name));
            students1.Select(c => c.Name).Should().EndWith(students2.Select(c => c.Name));
        }

        public class Student
        {
            public string Name { get; set; }
        }
    }
}

Fluent assertions也有一些方法支持直接判断里面的元素

using FluentAssertions;
using Xunit;
namespace MyFirstUnitTests
{
    public class MyTestClass
    {
        [Fact]
        public void Test_Example1()
        {
            var students1 = new Person[]
            {
                new Student() { Name = "a1" },
                new Student() { Name = "a1" }
            };

            var s = new Student() { Name = "a1" };
            // 是不是子元素都可以赋值给Student
            students1.Should().AllBeAssignableTo<Student>();
            // 是不是子元素都是 Student类型
            students1.Should().AllBeOfType<Student>();

            students1.Should().AllBeAssignableTo<Person>(); //断言成功。因为Student继承于Person 
            //students1.Should().AllBeOfType<Person>(); //断言失败,因为元素的实际类型是 Student
            students1.Should().AllBeEquivalentTo(s);//是不是每个元素都跟s一样 (里面的值相等就行)
        }

        public class Student : Person
        {

        }

        public class Person
        {
            public string Name { get; set; }
        }
    }
}

对集合内的每一个元素进行断言

using FluentAssertions;
using Xunit;
namespace MyFirstUnitTests
{
    public class MyTestClass
    {
        [Fact]
        public void Test_Example1()
        {
            var students1 = new Student[]
            {
                new Student() { Name = "a1" },
                new Student() { Name = "a2" }
            };

//有两个元素就要写两个 action
            students1.Should().SatisfyRespectively(
                first =>
                {
                    first.Name.Should().Be("a1");
                },
                second =>
                {
                    second.Name.Should().Be("a1");
                });
        }

        public class Student
        {
            public string Name { get; set; }
        }
    }
}

这边也可以换成下面的这种方式,看起来更简单了,更方便

using FluentAssertions;
using Xunit;
namespace MyFirstUnitTests
{
    public class MyTestClass
    {
        [Fact]
        public void Test_Example1()
        {
            var students1 = new Student[]
            {
                new Student() { Name = "a1" },
                new Student() { Name = "a2" }
            };
            students1[0].Name.Should().Be("a1");
            students1[1].Name.Should().Be("a2");
        }

        public class Student
        {
            public string Name { get; set; }
        }
    }
}

最近更新的
...