繁体   English   中英

断言动态集合中两个不同的对象是否具有相同的值

[英]Assert if two different objects have same values in a dynamic collection

在比较动态集合(ViewBag)中的两个对象时,xUnit.net遇到了一个相当奇怪的问题。

我有一个具有以下方法的ActionFilter:

public void OnActionExecuting(ActionExecutingContext filterContext)
{
    var selectList = new List<SelectListItem>();

    var foos = _repo.Get();
    foreach (var foo in foos)
    {
        var selectItem = new SelectListItem()
        {
            Text = foo.Text,
            Value = foo.Value
        };
        selectList.Add(selectItem);
    }
    filterContext.Controller.ViewBag.SelectList = selectList;
}

请注意如何将值包装在List<SelectListItem> ,然后将其分配给ViewBag

然后,我进行了一个测试,测试是否将存储库中的值添加到ViewBag中:

public void MyTest()
{
    // Arrange
    var fakeController = Substitute.For<Controller>();
    var fakeContext = Substitute.For<ActionExecutingContext>();
    fakeContext.Controller = fakeController;

    var repository = Substitute.For<IRepository<Foo>>();
    var foo = new Foo() {Text = "Foo", Value = "Bar"};
    var foos = new List<Foo> { foo };
    repository.Get().Returns(foos);

    var filter = new MyFilter(repository);

    // Act
    filter.OnActionExecuting(fakeContext);

    // Assert
    var expected = new List<SelectListItem> {new SelectListItem {Text = foo.Text, Value = foo.Value}};
    Assert.Equal(expected, fakeContext.Controller.ViewBag.SelectList); // fails
}

该测试失败,并

结果消息:
Assert.Equal()失败

预期值:列表[SelectListItem {Disabled = False,Group = null,Selected = False,Text =“ Foo”,Value =“ Bar”}]

实际:列表[SelectListItem {禁用= False,组= null,已选择= False,文本=“ Foo”,值=“ Bar”}]

在我看来,这是平等的。

以防万一,我测试了是否意外检查了是否是同一实例。 但是下面通过了。 事实并非如此。

var a = new {a = "a"};
var b = new {a = "a"};
Assert.Equal(a, b); // pass

Assert.Equal将调用对象的“ Equals”方法。 对于List,它只是从Object继承而来,对于Object,引用类型将测试实例是否相等(即同一实例)。

相反,请尝试Enumerable.SequenceEqual(请参阅此处

更新以包括EqualityComparer的实现:

    // Custom comparer for the SelectListItem class
    class SelectListItemComparer : IEqualityComparer<SelectListItem>
    {
        // Products are equal if their names and product numbers are equal.
        public bool Equals(SelectListItem x, SelectListItem y)
        {

            //Check whether the compared objects reference the same data.
            if (Object.ReferenceEquals(x, y)) return true;

            //Check whether any of the compared objects is null.
            if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
                return false;

            //Check whether the products' properties are equal.
            return x.Text.Equals(y.Text) && x.Value.Equals(y.Value);
        }

        // If Equals() returns true for a pair of objects 
        // then GetHashCode() must return the same value for these objects.

        public int GetHashCode(SelectListItem item)
        {
            //Check whether the object is null
            if (Object.ReferenceEquals(item, null)) return 0;

            //Get hash code for the Name field if it is not null.
            int hashText = item.Text == null ? 0 : item.Text.GetHashCode();

            //Get hash code for the Code field.
            int hashValue = item.Value.GetHashCode();

            //Calculate the hash code for the product.
            return hashText ^ hashValue;
        }

    }

然后我们可以做:

        // Assert
        var expected = new List<SelectListItem> {new SelectListItem {Text = "this", Value = "that"}};
        var actual = new List<SelectListItem> {new SelectListItem {Text = "this", Value = "that"}};
        Assert.IsTrue(expected.SequenceEqual(actual, new SelectListItemComparer()));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM