复杂对象的断言

使用Fluent assertions对复杂对象的断言,是非常方便的。

有时候我们系统里面经常会有一些将 Api 的Model对象转成Service的Dto对象的情况。而这个转型我们也需要做单元测试。并且希望下次如果有新加属性的时候。也要求能转换准确。不要漏转了。

 public class MyTestClass
    {
        [Fact]
        public void MyTest()
        {
            var s = new Student() { Age = 1, Name = "ab2" };
            var dto = Convert(s);

            //我们只要用BeEquivalentTo 它就会自动对比这个对象下面的所有属性。
            dto.Should().BeEquivalentTo(s);

        }

        public StudentDto Convert(Student s)
        {
            return new StudentDto()
            {
                Age = s.Age,
                Name = s.Name
            };
        }
    }

    public class Student
    {
        public int Age { get; set; }

        public string Name { get; set; }
        //还有很多其它的属性
    }

    public class StudentDto
    {
        public int Age { get; set; }

        public string Name { get; set; }
    }

显式排除某些属性

两个对象属性不一致的情况。 比如说 Student有多了一个属性 AA 但是 StudtioDto没有这个属性

  public class Student
    {
        public int Age { get; set; }

        public string Name { get; set; }

        public string AA { get; set; }

        public string BB { get; set; }
    }

    public class StudentDto
    {
        public int Age { get; set; }

        public string Name { get; set; }

    }

忽略不存在的属性

通过 使用options.ExcludingMissingMembers()忽略不存在的成员

public class MyTestClass
    {
        [Fact]
        public void MyTest()
        {
            var s = new Student()
            {
                Age = 1,
                Name = "ab2",

            };
            var dto = Convert(s);
            dto.Should().BeEquivalentTo(s,
                options => options.ExcludingMissingMembers());

        }

        public StudentDto Convert(Student s)
        {
            return new StudentDto()
            {
                Age = s.Age,
                Name = s.Name,

            };
        }
    }
  

忽略指定的属性

但是上面的例子 会有一个缺陷。就是我们新加一些属性的时候这个单元测试是会通过的。 所以我们可能需要单独排除某些属性。

[Fact]
public void MyTest()
{
    var s = new Student()
    {
        Age = 1,
        Name = "ab2",

    };
    var dto = Convert(s);
    dto.Should().BeEquivalentTo(s,
        options => options.Excluding(x => x.AA)//排除 AA
        .Excluding(x => x.BB));//排除 BB
    //上面的断言还可以改成, 
        dto.Should().BeEquivalentTo(s,
                options => options.Excluding(x => x.SelectedMemberPath == "AA" | x.SelectedMemberPath == "BB"));
}

使用自己的比较行为

假设有一些属性名是Date结尾 我们转型或者做一些操作允许它的时间出现一定的变化(比如说转时区等).这样比较的时候我们就需要对这个字段进行特殊判断了。

[Fact]
public void MyTest()
{
    var s = new Student()
    {
        Age = 1,
        Name = "ab2",
        BirthDate = DateTime.Now
    };
    var dto = Convert(s);
    dto.Should().BeEquivalentTo(s,
        options => options.Using<DateTime>(ctx => ctx.Subject.Should().BeCloseTo(ctx.Expectation, 4000))
        .When(info => info.SelectedMemberPath.Contains("Date")));

}

public StudentDto Convert(Student s)
{
    return new StudentDto()
    {
        Age = s.Age,
        Name = s.Name,
        BirthDate = s.BirthDate.AddSeconds(3)
    };
}
}

public class Student
{
    public int Age { get; set; }

    public string Name { get; set; }

    public DateTime BirthDate { get; set; }
}

public class StudentDto
{
    public int Age { get; set; }
    public string Name { get; set; }
    public DateTime BirthDate { get; set; }
}
最近更新的
...