XUnit 模拟传递和断言集合

Posted

技术标签:

【中文标题】XUnit 模拟传递和断言集合【英文标题】:XUnit Mocking Passing and Asserting a Collection 【发布时间】:2022-01-05 07:32:28 【问题描述】:

XUnit 新手并尝试测试以下方法,但测试失败。 我相信原因是在调用断言时创建了一个新的数据实例。 所以即使认为结果与对象引用相同。

当向集合中添加新记录时,它应该返回添加的相同记录。

员工数据类:

    public class EmployeeData
    
        public int Id  get; set; 
        public string LastName  get; set; 
        public string FirstName  get; set; 
        public string Title  get; set; 

    

测试方法:

        public List<EmployeeData> Add(List<EmployeeData> employees)
        

            foreach(var employee in employees)
            
                data.Add(new EmployeeData()  Id = newId(), 
                        FirstName = employee.FirstName, LastName = employee.LastName, 
                        Title = employee.Title );
            

            return data;
        

测试方法:

        [Fact]
        public void Add()
        
            // Arrange
            var data = new List<EmployeeData>();

            data.Add(new EmployeeData()  Id = 1, FirstName = "Adams", LastName = "John", Title = "Fireman" );

            // Mocking the employee class constructor arguments.
            var mockLogging = new Mock<ILogger<DataService>>();
            var mockConfig = new Mock<IConfiguration>();
            var sut = new Employee(mockLogging.Object, mockConfig.Object);

            var result = sut.Add(data);

            // Assert should return the exact data inputted
            Assert.Equal(result, data);
        

测试结果:

  Message: 
Assert.Equal() Failure
Expected: List<EmployeeData> [EmployeeData  FirstName = "Adams", Id = 1, LastName = "John", Title = "Fireman" ]
Actual:   List<EmployeeData> [EmployeeData  FirstName = "Adams", Id = 1, LastName = "John", Title = "Fireman" ]

【问题讨论】:

你能用CollectionAssert.AreEquivalent()吗? @SteveWong 这不适用于 XUnit。 您是否尝试过覆盖 EmployeeData 类中的 EqualsGetHashCode 方法? Add方法中没有看到要声明的数据变量? 结果为真。因为值相同,但它们的引用彼此不同。你可以试试这个 Enumerable.SequenceEqual(list1, list2) -> docs.microsoft.com/en-us/dotnet/api/… 【参考方案1】:

EmployeeData 等于 EmployeeData 是什么意思? 您可以覆盖EmployeeData 类中的Equals 方法。

        public override bool Equals(object obj)
        
            return this.FirstName == ((EmployeeData)obj).FirstName;
        

第二个选项是将IEqualityComparer&lt;T&gt; 传递给Equal 方法。

    public class GenericCompare<T> : IEqualityComparer<T> where T : class
    
        private Func<T, object> _expr  get; set; 
        public GenericCompare(Func<T, object> expr)
        
            this._expr = expr;
        
        public bool Equals(T x, T y)
        
            var first = _expr.Invoke(x);
            var sec = _expr.Invoke(y);
            if (first != null && first.Equals(sec))
                return true;
            else
                return false;
        
        public int GetHashCode(T obj)
        
            return obj.GetHashCode();
        
    

并使用它:

Assert.Equal<EmployeeData>(result, data, new GenericCompare<EmployeeData>(x => x.Id));

从https://***.com/a/23623976/6629020复制粘贴的GenericCompare

【讨论】:

以上是关于XUnit 模拟传递和断言集合的主要内容,如果未能解决你的问题,请参考以下文章

Xunit常用断言整理&带一点Shouldly介绍

如何使用流利的断言结合集合和属性断言?

流利的断言;结合集合和对象图比较断言

接口测试执行工具Postman:模拟请求用例执行断言批量运行用例简单持续集成

xml 的流利断言

使用 Mock Service Worker 时如何对 graphql 查询变量进行断言?