c# - Assert if two different objects have same values in a dynamic collection -


i've run rather odd problem xunit.net when comparing 2 objects in dynamic collection (the viewbag).

i have actionfilter following method:

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; } 

note how values wrapped in list<selectlistitem> , assigned viewbag.

then have test tests if values repository added 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 } 

this test fails

result message:
assert.equal() failure

expected: list [selectlistitem { disabled = false, group = null, selected = false, text = "foo", value = "bar" }]

actual: list [selectlistitem { disabled = false, group = null, selected = false, text = "foo", value = "bar" }]

to me looks equal.

just in case tested if unexpectedly checking if same instance. below passes. that's not case.

var = new {a = "a"}; var b = new {a = "a"}; assert.equal(a, b); // pass 

assert.equal call object's "equals" method. list, inherited object, reference types tests instance equality (i.e.. same instance).

instead, try enumerable.sequenceequal (see here )

updated include implementation of equalitycomparer:

    // custom comparer selectlistitem class     class selectlistitemcomparer : iequalitycomparer<selectlistitem>     {         // products equal if names , product numbers equal.         public bool equals(selectlistitem x, selectlistitem y)         {              //check whether compared objects reference same data.             if (object.referenceequals(x, y)) return true;              //check whether of compared objects null.             if (object.referenceequals(x, null) || object.referenceequals(y, null))                 return false;              //check whether products' properties equal.             return x.text.equals(y.text) && x.value.equals(y.value);         }          // if equals() returns true pair of objects          // gethashcode() must return same value these objects.          public int gethashcode(selectlistitem item)         {             //check whether object null             if (object.referenceequals(item, null)) return 0;              //get hash code name field if not null.             int hashtext = item.text == null ? 0 : item.text.gethashcode();              //get hash code code field.             int hashvalue = item.value.gethashcode();              //calculate hash code product.             return hashtext ^ hashvalue;         }      } 

then can do:

        // 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())); 

Comments

Popular posts from this blog

html - Outlook 2010 Anchor (url/address/link) -

javascript - Why does running this loop 9 times take 100x longer than running it 8 times? -

Getting gateway time-out Rails app with Nginx + Puma running on Digital Ocean -